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]
Not sure what will be easiest for you to use/understand..I thought the patty approach pretty nice. That said, to answer your last question, the macros module has a few interesting things along the lines of what you were asking for: `parseExpr`, `parseStmt`, and `emit`. The first two can compile strings to ASTs and the last can do that and then put the resulting AST/code in your program. `emit` has a little example right in its definition in `macros.nim`. I think `emit` is probably what you were asking for.
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: Going to nim forum from Nim Home Page is redirecting back to home.
Works for me?
Going to nim forum from Nim Home Page is redirecting back to home.
Only direct link works.
Re: How to be more concise in code [NEWBIE]
import patty variant Message: Hit(hp: int) Death(died: string) proc writeMsg(m: Msg): string = match m: Hit(hp): result = "HIT " & $hp Death(died): result = "DEATH " & died Cannot get much shorter
Re: Writing Python extensions in Nim
wow **@blvd**, that looks like a high quality article. I only had a chance to skim it, but it's looking good. It's scary that I almost missed it (this thread is almost past the bottom), Nim articles are always encouraged! btw I hope you won't mind if I tweet about it using Nim's Twitter.
Re: Selectors module
Maybe the `asyncfile` module could help?
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.
Selectors module
In the selectors module, the register function registers the fd from socket. I need to use the equivalent of POSIX poll for files as well as sockets. Should I just use the posix module as the server will be linux or is there a portable way to do what I want in standard library?
Re: How to be more concise in code [NEWBIE]
> but did not want to use inheritance and methods because it needs heap > allocation You are using strings so your objects are doing heap allocations anyway. You should replace the strings with IDs of the target which got hit / died if you don't want any heap allocation. You can of course do something similar to dynamic dispatching without polymorphism: type MessageType = enum msgHit, msgDeath, msgDayNight type Message* = object textImpl: proc(m: Message): string case messageType*: MessageType of msgHit: target*: string hp*: int of msgDeath: died*: string of msgDayNight: isDay*: bool proc hit*(target: string, hp: int): Message = Message(messageType: msgHit, target: target, hp: hp, textImpl: proc(m: Message): string = "You hit " & m.target & " for " & $m.hp & " HP." ) proc death*(died: string): Message = Message(messageType: msgDeath, died: died, textImpl: proc(m: Message): string = m.died & " just died." ) proc dayNight*(isDay: bool): Message = Message(messageType: msgDayNight, isDay: isDay, textImpl: proc(m: Message): string = if m.isDay: result = "The day has just begun." else: result = "Beware! Night is coming." ) proc getText*(m: Message): string = m.textImpl(m)
Re: Book for beginners
@Libman I am grateful that you are interested, I might do something like MEAP style (Manning Early Access Program), which is useful for both parties.
Re: How to be more concise in code [NEWBIE]
I have created two macros exactly for this purpose! [https://github.com/andreaferretti/patty](https://github.com/andreaferretti/patty) The first one, called `variant` or `variantp` (for public), generate the types and the three constructor functions. The second one, called `match`, can be used to implement `getText`
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: Should nim runtime catch signals like SIGFPE and raise an exception by default?
>From excpt's source code, it was written with systems without exceptions in >mind: Exception handling code. Carefully coded so that tiny programs which do >not use the heap (and nor exceptions) do not include the GC or memory >allocator. You can set a custom message however: errorMessageWriter = proc(m: string) = echo "Custom: ", m var i = 0 echo 5 div i # Custom: Traceback (most recent call last) # main.nim(5) main #system.nim(2534) sysFatal # Error: unhandled exception: division by zero [DivByZeroError] It depends on what you need, you probably prefer to set a [global/local exception handler](https://nim-lang.org/docs/system.html#globalRaiseHook): globalRaiseHook = proc (e: ref Exception): bool = echo "AY AY AY!" quit(1) var i = 0 echo 5 div i # AY AY AY! # exit status 1
Re: Dynamic Types
Krux's solution is the most efficient. You can also use inheritance: import strutils type BaseType = ref object of RootObj StringType = ref object of BaseType value: string IntType = ref object of BaseType value: int method toString(bt: BaseType): string {.base.} = "" method toString(st: StringType): string = st.value method toString(it: IntType): string = $it.value proc getArg(typeName:string, strValue:string):BaseType= case typeName: of "string": result = StringType(value: strValue) of "int": result = IntType(value: parseInt(strValue)) let bt = getArg("int", "777") echo "ToString: ", toString(bt) if bt of StringType: echo("Casting: ", StringType(bt).value) elif bt of IntType: echo("Casting: ", IntType(bt).value) [run it](https://glot.io/snippets/en6i60pzu6)