Re: How to be more concise in code [NEWBIE]

2017-02-16 Thread mmierzwa
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]

2017-02-16 Thread cblake
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]

2017-02-16 Thread mmierzwa
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.

2017-02-16 Thread Araq
Works for me?


Going to nim forum from Nim Home Page is redirecting back to home.

2017-02-16 Thread v3ss0n
Only direct link works.


Re: How to be more concise in code [NEWBIE]

2017-02-16 Thread andrea

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

2017-02-16 Thread dom96
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

2017-02-16 Thread dom96
Maybe the `asyncfile` module could help?


Re: How to be more concise in code [NEWBIE]

2017-02-16 Thread mmierzwa
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

2017-02-16 Thread h42
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]

2017-02-16 Thread flyx
> 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

2017-02-16 Thread Octopoda
@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]

2017-02-16 Thread andrea
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]

2017-02-16 Thread mmierzwa
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?

2017-02-16 Thread Arrrrrrrrr
>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

2017-02-16 Thread Arrrrrrrrr
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)