Re: Nim forum features
@Araq Thank you. Of course it was my mistake. I used wrong account and that list was just empty. @juancarlospaco Thanks. Why I did not get that idea myself... ;)
Re: Version 0.17.0 released!
First of all. Congratulations. > But you're spot on, I hope this feature means we can remove method from the > language. If you do, you may consider put some words into documentation what to do to achieve similar behaviour because there is quite a lot of people that are comfortable with that approach.
Re: How not to use methods
Jonathan Blow is creating this language and compiler and actually as testing he is making a game in it. There you can declare things as SOA or AOS (struct of arrays or array of structs). I encourage you to visit his videos sessions on youtube. So it exists but is not available yet.
Re: How not to use methods
Thank you for your explanation. Whereas I can understand I am not good at applying this knowledge in practise. First lets take a look at object variant polymorphism. It can do the same as methods but then cases sneak everywhere which is ugly. Then, let me elaborate more. There are entities. Entities does not have basically anything interesting by themselves but list of components. Components are responsible for different behaviours and they can be attached or removed. So basically I do not know what components entity will have. Then I have a command. I present such command to every component until it is consumed by any. Sometimes there are more components which can take the same command. For instance flyer and walker both can take "move" command and execute it in its own way. This prevents me from adding separate table for every component and process them one by one. I know that it is not as performant but leave performance for now.
Re: Immutable sequence
Thank you. From my examples also I realized that I am tending to mix reference semantics with value semantics which lead to quite frustrating bugs.
Immutable sequence
I have found such example when seq is immutable type B* = object myseq: seq[int] type A* = object bseq*: seq[B] proc test1() = var b: B b.myseq = newSeq[int]() var i = 0 while i < len(b.myseq): if b.myseq[i] == 10: b.myseq.del(i) # mutable proc test() = var b: B b.myseq = newSeq[int]() var a: A a.bseq = newSeq[B]() var j = 0 while j < len(a.bseq): var myb = a.bseq[j] var i = 0 while i < len(myb.myseq): myb.myseq.del(i) # mutable i += 1 j += 1 proc test2() = var b: B b.myseq = newSeq[int]() var a: A a.bseq = newSeq[B]() for myb in a.bseq: var i = 0 while i < len(myb.myseq): myb.myseq.del(i) # immutable i += 1 It seems that in test2 it is "for myb in a.bseq" which makes later myb.myseq immutable but with comparison to test1 and test I have feeling that it is a bit inconsistent. Why "for myb in a.bseq:" makes it immutable whilst myb = a.bseq[j] not? Or maybe I am wrong at all...
Re: How not to use methods
Yes. First I am afraid they could remove them, second and more important, it means they do such things in different way which I would like to learn.
Re: How not to use methods
Thank you. Would you mind to present "colsure" solution? The one you suggested would not be feasible as every entity can have various nubmer of various components.
How not to use methods
Hi I need a hint. Provided I have such construction type Component = ref object of RootObj type Entity = ref object components = seq[Component] method update(c: Component) = discard Then, I have components, like: type Fighter = ref object of Component method update(c: Fighter) = discard Finally for c in entity.components: c.update() So it is quite common pattern. Collection of objects with common interface on which you perform some action. How can I preserve such functionality avoiding using methods (as I have heard core team do not like them).
Method does not work, implicit generic?
Hi I have had hard time with method which did not behave as I expected to. child.nim type Parent* = ref object of RootObj type Child* = ref object of Parent type Some = object method getDataToSave*(x: Parent): object {.base.} = echo("took getDataToSave Parent") var o: Some return o method getDataToSave*(x: Child): object = echo("took getDataToSave from Child") var o: Some return o main.nim from child import Parent, Child, getDataToSave proc test() = var x: Parent = Child() discard getDataToSave(x) test() It compiles and gives "took getDataToSave from Parent", whilst I expected method on Child would be invoked. After long long time I noticed that problem lies in return type which is object. If you change child.nim type Parent* = ref object of RootObj type Child* = ref object of Parent type Some = object method getDataToSave*(x: Parent): Some {.base.} = echo("took getDataToSave Parent") var o: Some return o method getDataToSave*(x: Child): Some = echo("took getDataToSave from Child") var o: Some return o It is working as expected, which means I get "took getDataToSave from Child". Perhaps compiler should give warning?
Re: 7drl - Seven Day Roguelike Game Dev Competition
I do not know the rules. But if anyone would like to write it in Nim I would be happy to join. Recently I was working on something that resemble Roguelike: [Not Roguelike!](https://dl.dropboxusercontent.com/u/21455945/NotRoguelike.GIF)
Re: Atom/Sublime with recent versions of nimsuggest
Sublime works decent with nimlime. However it was recently abandoned so I am a bit worried.
Re: Nim video tutorials
Great idea. Rather short videos focused on particular subject. Worth mentioning is basics, how to install, how to use, hello world, then syntax, datatypes, object model, ref and without ref. More advanced topics could cover generics, templates, marros. Now please bear in mind that I am not particular fan of design patterns, but, in Nim, thanks to its specification some useful patterns emerges and can be used to overcome difficulties. It would be fantastic to identify them, gather. It does not have to be related to objects composition like in java. It could be related to variadic objects (that use case), how to implement mutually redundant types in a clean way, when and how to use templates, when, let, const etc. Some episodes could be "special" and focus on some interesting libraries, systems, programs that are worth mentioning. Then we have interviews. Like interview with core dev team with subject "Future of Nim". Ok, I think I let my imagination fly.
Re: Nim Syntax ''Skins''
Just remark. In SQL Server for instance you can design query graphically but everyone (in my experience) just write it in text. I am trying to say that it would not be easy to go to higher level of abstraction. Graphical languages are not very popular. Human is a beast which thinks rather sequentially and text mirrors that behaviour. If we want to drag people here making syntax looking familiar to them I am afraid that it is wrong approach. They will go anyway. I think when you choose language you have many more serious considerations. Especially when you know few other languages it does not matter if curly braces or not. Also I am afraid that we have relatively small community and instead of uniting we are going to split it to smaller incompatible camps.
Re: Nim Syntax ''Skins''
I think that also the question is whether we (you rather) are making practical language or academic one. I am not sure if both can be successfully combined (although such approach worked for pypy they say). Endow language with all shiny, "it is how it should be" etc. concepts, which can by the way confuse people, can (when not careful) make a garbage. But let's make 1.0 version. Make it useful, stable, not bugged, otherwise it will never end.
Re: Nim Syntax ''Skins''
While I agree with everything what Libman says I am also a bit afraid. * syntax wars will not be ceased in peaceful Nim world, they will be drag inside Nim world * Nim already allows using quite different styles. And it happens quite often that I am looking at someone's code and it take me time to understand. I loved that in Python with its quite easy schematic syntax and not many keywords I was able to pickup programs just by looking at them. * Programs are written by people and read by people. I do not care about AST. If I see two programs in Nim written in different syntax it is not very different situation for me if they were actually written in different languages. And so if I see program written in F# it does not help that I know VB and C# and all three are compiled to CLR. * For a long run I doubt that it is existence or lack of curly braces in language that makes it good or bad (or popular). This is only excuse in most cases. Programming in a specific language I am able to adapt to its specification. I want it to be concise, clear and allowing me to implement what I have on my mind. Also easy read examples and documentation. * It is already frustrating when I am adapting libraries or copy someone's else part of program and I find that it uses 2 spaces indentation (I am using 4 because then I can see better, using tabs would solve this problem, but it was discussed somewhere else so I need to live with that). I can imagine if I had to merge two Nim different syntax programs. Automatic conversion could help but it is just another step to do and I doubt it would be perfect.
Re: Why `..` does not work for countdown
>From system.nim iterator `..`[S, T](a: S; b: T): T {..} An alias for countup. Source Edit Anyway, could not it work with a > b? Probably there is some reasoning behind this and I am trying to understand.
Why `..` does not work for countdown
Hi I have been wondering why _`..`_ operator works only for _countup_. Why there is no counterpart for _couontdown_? For instance something like: when sizeof(int) <= 2: type IntLikeForCount = int|int8|int16|char|bool|uint8|enum else: type IntLikeForCount = int|int8|int16|int32|char|bool|uint8|uint16|enum iterator `..`[S, T](a: S, b: T): T {.inline.} = dbg("Using .. for ", a, ", ", b) if a > b: when T is IntLikeForCount: var res = int(a) while res >= int(b): yield T(res) dec(res, 1) else: var res = a while res >= b: yield res dec(res, 1) else: when T is IntLikeForCount: var res = int(a) while res <= int(b): yield T(res) inc(res) else: var res: T = T(a) while res <= b: yield res inc(res) Perhaps it is naive approach but I assume that it could be written to resemble currently existing _`..`_ implementation.
File, FileDescriptor, Handle, Windows
Hi I would like to ask you for help again. I am trying to achive double buffering for console under Windows (I was in shock when I noticed that there is double buffering for console). My current code: import winim from os import execShellCmd, sleep var buffer1: HANDLE = GetStdHandle(STD_OUTPUT_HANDLE) var buffer2: HANDLE = CreateConsoleScreenBuffer( GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL) discard execShellCmd("cls") var begin: COORD begin.X = 0; begin.Y = 0; SetConsoleCursorPosition(buffer1, begin) var written: DWORD; var s: wstring = `+$`[wstring]("milk!") var s1: wstring = `+$`[wstring]("choco") WriteConsole( buffer1, &s, 5, addr written, NULL) echo "buffer 1" WriteConsole( buffer2, &s1, 5, addr written, NULL) proc open_osfhandle(osfhandle: Handle, flags: int): int {.importc: "_open_osfhandle", header: "io.h".} proc fdopen(fd: int, mode: char): FILE {.importc: "_fdopen", header: "stdio.h".} var fd = open_osfhandle(buffer1, 8) echo "FD: ", fd # This line produces error # SIGSEGV: Illegal storage access. (Attempt to read from nil?) # var f = fdopen(fd, 'a') # <- ERROR #f.write("2 buf") sleep(2000) SetConsoleActiveScreenBuffer( buffer2 ) sleep(2000) SetConsoleActiveScreenBuffer( buffer1 ) So I have found that required functions are fortunately wrapped in _winim_. Fantastic, I could rewrite c++ code without almost any changes. And it works. However, having this I would like to be able to just use standard _"write"_ Nim procedure. Then the problems started to pile up. I need Nim _File_ having c _HANDLE_. I have found that I can change _HANDLE_ to FILE* in c by obtaining first file descriptor using __open_osfhandle_ and then get FILE* from FD using __fd_open_. I tried but I find difficult to map c types to Nim and back. In example code I have error. Could you help me?
Re: How to be more concise in code [NEWBIE]
Thank you. Will take a look. I am looking for simple solutions. Patty is for sure marvellous but 400 lines (or so) of code to emit few lines of code is intimidating to me.
Re: How to be more concise in code [NEWBIE]
So final version from my first post would now look like: (I took variantp from andrea's patty and added my version of match) template match*(t: typed, handlers: openArray): untyped = var x = ord(t.kind) handlers[x](t) message.nim import patty variantp Message: msgHit(target: string, hp: int) msgDeath(died: string) msgDayNight(isDay: bool) # normally queue var messages*: Message proc getTextHit(m: Message): string = "You hit " & m.target & " for " & $m.hp & " HP." proc getTextDeath(m: Message): string = m.died & " just died." proc getTextDayNight(m: Message): string = if m.isDay: result = "The day has just begun." else: result = "Beware! Night is coming." proc getText*(m: Message): string = match(m, [getTextHit, getTextDeath, getTextDayNight]) main.nim from message import msgDayNight, messages, getText # game time system proc informAboutDay() = messages = msgDayNight(isDay = true) # player informer proc update() = echo( getText(messages) ) when isMainModule: informAboutDay() update() Sweet. Except two things. First andrea's version is complicated and I do not understand it, so if by accident it stops working with new version of nim i am doomed. Second, I do not understand how my simple _match_ version is working, even though I wrote it and it is working... BTW: Is it possible instead of playing with AST in macros to spit just code built from strings? Like in static block i could create few lines of code which would be then compiled as rest of normal code? I know, this is wrong approach and AST is proper but still...
Re: How to be more concise in code [NEWBIE]
Thank you **andrea**. I like your _variant_ but _match_ is for me similar in verbosity to my getText and I think it could be compressed further. My attempt: import patty variant Message: hit(hp: int) death(died: string) proc hhit(m: Message) = echo "HIT " & $m.hp proc hdeath(m: Message) = echo "DEATH" & m.died template choose(t: typed, handlers: tuple) = #var x = ord(t.kind) #handlers[x]() # - compilation error: cannot evaluate at compile time case ord(t.kind) of 0: handlers[0](t) of 1: handlers[1](t) proc test() = var h = hit(5) choose(h, (hhit, hdeath)) test() It works nice, but I cannot overcome problem with variable amount of handlers. Thank you **flyx**. When death message is dispatched entity is already removed so having ID I would not be able to fetch name, and you will have to make string somewhere anyway to display it - so this is not my concern. Your solution is also very interesting.
How to be more concise in code [NEWBIE]
Hi I needed some sort of polymorphism, but did not want to use inheritance and methods because it needs heap allocation and I have quite small objects which are created and destroyed frequently. Finally I came out with setup which I was comfortable with, and here is example: message.nim type MessageType = enum msgHit, msgDeath, msgDayNight type Message* = object case messageType*: MessageType of msgHit: target*: string hp*: int of msgDeath: died*: string of msgDayNight: isDay*: bool # normally queue var messages*: Message proc hit*(target: string, hp: int): Message = Message(messageType: msgHit, target: target, hp: hp) proc death*(died: string): Message = Message(messageType: msgDeath, died: died) proc dayNight*(isDay: bool): Message = Message(messageType: msgDayNight, isDay: isDay) proc getTextHit(m: Message): string = "You hit " & m.target & " for " & $m.hp & " HP." proc getTextDeath(m: Message): string = m.died & " just died." proc getTextDayNight(m: Message): string = if m.isDay: result = "The day has just begun." else: result = "Beware! Night is coming." proc getText*(m: Message): string = case m.messageType: of msgHit: result = getTextHit(m) of msgDeath: result = getTextDeath(m) of msgDayNight: result = getTextDayNight(m) else: result = "UNKNOWN MESSAGE" main.nim from message import dayNight, messages, getText # game time system proc informAboutDay() = messages = dayNight(isDay = true) # player informer proc update() = echo( getText(messages) ) when isMainModule: informAboutDay() update() [snippet](https://glot.io/snippets/en6lyc2oyi) It is simple, it is clear but it is very verbose. What would you suggest to preserve merits while allowing addition of new MessageTypes easier. Currently it consist in: 1. Add message type in MessageType 2. Add "of" condition in Message 3. Add "of" in getText 4. Provide constructor 5. Provide handler Also I would not like to solve this problem introducing another overly complicated layer (like not simple templates for instance). All suggestions appreciated. Regards Michal "Very bad coder." \- You have been warned!
Re: messaging - or communicating between GUI's
Thank you **god**. data[][0].addr was what I was looking for, tried to use repr to check but it turned out unreliable and so my confusion. So **Araq** was right, I was trying to send pointer, but I could not find from his answer where I made it wrong.
Re: var param vs tuple as return value
I know. Closed. I am sorry but let me add last quick remark. Such discussions, even when look somewhat as a fight, are not necessarily bad thing. It is good to see some other people opinions as long as they are backed up with constructive arguments. So if it is possible to make section for my questions , maybe it is possible to also create section for more loose discussions? I hate when I see interesting debate on stackoverflow and suddenly it is closed because someone found it not constructive.
Re: messaging - or communicating between GUI's
My understanding is that I **do not** send pointer but I give address of start of memory from which pipe should send the data of bytes length. And the pipe is to cross the processes barrier. Also I have no idea how or what could I use from stdlib.
Re: messaging - or communicating between GUI's
So I modified god's example. The main differrence is that server receives data and client pushes and data should be string. Unfortunatelly after many many hours i gave up and would like to ask you for help again. I feel I am doing something terrible with strings and its places in memory. server import winlean, os type Msg = cstring import strutils import typetraits # Auxilary proc rr[T](v: ptr T) = echo "Type: ", name(T), " Addr: ", toHex(cast[int](v)), " Val: ", v[] proc rr(v: pointer, t: typedesc) = echo "Type: ", name(pointer), " Addr: ", toHex(cast[int](v)), " val ", name(t), ": ", (cast[ptr t](v))[] template leave = if(true): return # proc connectNamedPipe(hNamedPipe: Handle, lpOverlapped: pointer): WINBOOL {.importc: "ConnectNamedPipe", stdcall, dynlib: "kernel32".} const pipeHeaderName = r"\\.\pipe\dbgpipe" const PIPE_READMODE_BYTE = 0x'i32 ERROR_PIPE_BUSY = 231 var pipe:Handle proc createPipe() = echo "Creating an instance of a named pipe ..." var pipeName = newWideCString(pipeHeaderName) pipe = createNamedPipe(pipeName, # name of the pipe PIPE_ACCESS_INBOUND, # 1-way pipe -- receive only PIPE_READMODE_BYTE, 1, # only allow 1 instance of this pipe 0, # no outbound buffer 0, # no inbound buffer 0, # use default wait time nil) if pipe == INVALID_HANDLE_VALUE: echo "Failed to create inbound pipe instance." let err = osLastError() if err.int32 != ERROR_PIPE_BUSY: raiseOsError(err) echo "Waiting for a client to connect to the pipe..." # This call blocks until a client process connects to the pipe var res = connectNamedPipe(pipe, nil) if res == 0: echo "Failed to make connection on named pipe." # look up error code here using GetLastError() discard closeHandle(pipe) # close the pipe proc recvMessage(buffer: ptr Msg ):bool = result = false var msglen = 0.int32 res = 0.int32 try: discard pipe.peekNamedPipe(cast[pointer](buffer), (4).int32, msglen.addr) # not blocking except: return false echo("Expected msg bytes: ", 4) echo("Bytes to read in pipe: ", msglen) if msglen == 0: return false var numBytesRead:int32 = 0 try: res = readFile(pipe, cast[pointer](buffer), # the data from the pipe will be put here (4).int32, numBytesRead.addr, # this will store number of bytes actually read nil) except: return false if res > 0: echo "Number of bytes read: ", numBytesRead echo "Message: " rr(buffer, Msg) return true else: echo "Failed to read data from the pipe." proc test() = createPipe() var b:Msg = "ABC" rr(addr b) var i = 4 while i > 0: i -= 1 if recvMessage(addr b): rr(addr b) sleep(500) echo "ver ", 40 test() client import winlean, os type Msg = cstring const pipeHeaderName = r"\\.\pipe\dbgpipe" const ERROR_PIPE_BUSY = 231 var pipe:Handle proc connectPipe() = echo "Connecting to pipe..." var pipeName = newWideCString(pipeHeaderName) var sa = SECURITY_ATTRIBUTES(nLength: sizeof(SECURITY_ATTRIBUTES).cint, lpSecurityDescriptor: nil, bInheritHandle: 1) pipe = createFileW(pipeName, GENERIC_WRITE, 0, sa.addr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0) if pipe == INVALID_HANDLE_VALUE: echo "Failed to connect to pipe." let err = osLastError() if err.int32 != ERROR_PIPE_BUSY: raiseOsError(err) proc closePipe*() = # Close the pipe (automatically disconnects client too) discard closeHandle(pipe) proc sendMessage*(data: ptr Msg) = echo "Sending data to pipe..." var numBytesWritten:int32 = 0 res:int32 = 0 echo "Writing: ", len(data[]), " chars, sizeof ", sizeof(data[]) try: res = writeFile(pipe, # handle to our outbound pipe
Re: [newbie question] Pointer to cstring
Thank you Krux and Araq. repr is very useful to be able to understand what is going on in my program. I am trying to send strings through a pipe (without success) so casting to pointer and knowing what is exactly happening is crucial for me.
[newbie question] Pointer to cstring
Hi I am having hard time understanding pointers, addr, cstrings. var i: cstring = "a" var pi: ptr cstring = i.addr echo repr(i) echo repr(pi) Output: 005BC058"a" ref 004477F8 --> 005BC070"a" My understanding is this. First we declare variable i and assign string "a" there. As first line of output says, "a" is kept in ...058 cell of memory so in fact i contains address of this cell. Now we are declaring pointer pi and assign address of i. Is it that pi points to i that points to ...058 memory which contains "a"? As I understand from second ouput line address of pi variable is ...77F8, but then it is suggesting that "a" is in memory cell C070. I am a bit confused. Could you help me understand?
Re: messaging - or communicating between GUI's
Thank you for your reply **Krux02**, I appreciate it. Not quite there however because what I am interested in is processes not threads and how to set up communication between two. Also I am looking for pipes, shared memory, ffs and differences among them, performance etc. I do not want to setup communication through sockets. Nothing to do with GUI applications. **god**, thank you I think exactly what I am looking for. Will check your examples.
Re: messaging - or communicating between GUI's
Could you paste your solution (the IPC part) for future reference?
Re: var param vs tuple as return value
Thank you. I will use this IRC bridge. Anyhow, I feel forum is a lot better for even newbie questions. If language becomes more popular you will have the same questions asked again and again in IRC whilst they should be easy discoverable in forum (like in stackoverflow), this could serve as additional documentation with examples.
Re: How to open new console window and File, FileInfo, FileHandle
When I am in forum view I see there are 4 answers in this thread and I see also AironGregatti. However when I enter I see only 3 posts without that from Airon. Why is this so? Moderation?
Re: var param vs tuple as return value
Hi "Btw please join IRC or gitter instead of flooding this forum with newbie questions, no offense." I do not want to flood your forum, but I do realize my questions would be newbie as well. The problem is, if I use irc-like I have chance to get answer only from people who are already online/reading, then it is buried, while on forum it stays as separate thread. So for others possible newbie (I know there are not many newbie here, but for future?) it is easier to discover later. Maybe finding separate part of forum or something similar would be nice idea? Having said that, I am moving to gitter. Regards Michal
Re: Exploring namespaces support in Nim
Andrea, whilst its true, it is on library creator side, whilst we may want to decide how it would look like in our code, when there are two libraries where their creators did not use distinct type.
How to open new console window and File, FileInfo, FileHandle
Hi I am trying to open new console window and be able to write to it. My attempts failed. How to do that? (currently using MinGW) During my attempts I tried to create process using startProcess I noticed that I can get then FileHandle for process. However I do not know how obtain File to which I could write (like stdout), I also have seen FileInfo. So having File, FileHandle, FileInfo - could someone give some hints about them? I could also fetch input Stream. Third. Is it difficult (it is not, but for me it is) to switch to vcc compiler? Are there any easy manual for that? Thanks in advance for any help. Regards Michal /The really bad programmer/