Re: dynamically creating a tuples

2017-08-01 Thread flyx
Have you seen [this thread](https://forum.nim-lang.org/t/2482)?

>From what you're writing, it is hard to understand what you want to do.


Re: Upgrading to Nim 0.17.0

2017-07-10 Thread flyx
Okay, that worked. Should have tried beforehand, but I though removing all 
`nimcache` dirs should be sufficient.


Upgrading to Nim 0.17.0

2017-07-06 Thread flyx
I am trying to update Nim to 0.17.0. I am on current master branch. Since 
rebuilding with koch failed, I updated the csources and built nim from there – 
no problems.

Then, I try to rebuild koch with the new Nim. This generates the following 
error output:


Hint: used config file '/Users/flyx/Projects/3rdParty/Nim/config/nim.cfg' 
[Conf]
Hint: used config file '/Users/flyx/Projects/3rdParty/Nim/koch.nim.cfg' 
[Conf]
Hint: system [Processing]
Hint: koch [Processing]
Hint: os [Processing]
Hint: strutils [Processing]
Hint: parseutils [Processing]
Hint: math [Processing]
Hint: algorithm [Processing]
Hint: times [Processing]
Hint: posix [Processing]
Hint: parseopt [Processing]
Hint: osproc [Processing]
Hint: strtabs [Processing]
Hint: hashes [Processing]
Hint: etcpriv [Processing]
Hint: streams [Processing]
Hint: cpuinfo [Processing]
Hint: kqueue [Processing]
CC: compiler_koch
CC: stdlib_system
CC: stdlib_os
CC: stdlib_strutils
CC: stdlib_parseutils
CC: stdlib_math
CC: stdlib_algorithm
CC: stdlib_times
Error: execution of an external compiler program 'clang -c  -w  
-I/Users/flyx/Projects/3rdParty/Nim/lib -o 
/Users/flyx/Projects/3rdParty/Nim/nimcache/stdlib_strutils.o 
/Users/flyx/Projects/3rdParty/Nim/nimcache/stdlib_strutils.c' failed with exit 
code: 1

/Users/flyx/Projects/3rdParty/Nim/nimcache/stdlib_strutils.c:322:30: error: 
expected ';' after expression
nimfr_("find", "system.nim")
    ^
;
/Users/flyx/Projects/3rdParty/Nim/nimcache/stdlib_strutils.c:364:34: error: 
expected ';' after expression
nimfr_("contains", "system.nim")
    ^
;
/Users/flyx/Projects/3rdParty/Nim/nimcache/stdlib_strutils.c:379:34: error: 
expected ';' after expression
nimfr_("contains", "system.nim")
^
;
/Users/flyx/Projects/3rdParty/Nim/nimcache/stdlib_strutils.c:393:28: error: 
expected ';' after expression
nimfr_("*=", "system.nim")
  ^
  ;
/Users/flyx/Projects/3rdParty/Nim/nimcache/stdlib_strutils.c:400:28: error: 
expected ';' after expression
nimfr_("+=", "system.nim")
  ^
  ;
/Users/flyx/Projects/3rdParty/Nim/nimcache/stdlib_strutils.c:425:36: error: 
expected ';' after expression
nimfr_("intToStr", "strutils.nim")
  ^
  ;
/Users/flyx/Projects/3rdParty/Nim/nimcache/stdlib_strutils.c:466:34: error: 
expected ';' after expression
nimfr_("repeat", "strutils.nim")
^
;
/Users/flyx/Projects/3rdParty/Nim/nimcache/stdlib_strutils.c:492:31: error: 
expected ';' after expression
nimfr_("usrToCell", "gc.nim")
 ^
     ;
/Users/flyx/Projects/3rdParty/Nim/nimcache/stdlib_strutils.c:501:31: error: 
expected ';' after expression
nimfr_("rtlAddZCT", "gc.nim")
 ^
 ;
/Users/flyx/Projects/3rdParty/Nim/nimcache/stdlib_strutils.c:508:36: error: 
expected ';' after expression
nimfr_("asgnRefNoCycle", "gc.nim")
      ^
  ;
/Users/flyx/Projects/3rdParty/Nim/nimcache/stdlib_strutils.c:547:36: error: 
expected ';' after expression
nimfr_("parseInt", "strutils.nim")
  ^
  ;
/Users/flyx/Projects/3rdParty/Nim/nimcache/stdlib_strutils.c:621:40: error: 
expected ';' after expression
nimfr_("toLowerAscii", "strutils.nim")
  ^
  ;
/Users/flyx/Projects/3rdParty/Nim/nimcache/stdlib_strutils.c:644:40: error: 
expected ';' after expression
nimfr_("toLowerAscii", "strutils.nim")
  ^
   

Re: New here. can't seem to get the installer to work.

2017-04-24 Thread flyx
You have to give us some information to work with. For example, what C compiler 
are you using? And what's the output of the `sh build.sh` command when building 
from source? Since `bin/nim` doesn't exist afterwards, this is probably the 
problem, and the output most probably gives you the reason why it fails.


Re: Alternative for {.immediate.}

2017-04-07 Thread flyx
Shouldn't it suffice to make `e` `untyped`?


Re: How check if expression has a type without triggering compilation failure

2017-04-05 Thread flyx
… because it is mentioned in the [system module's 
documentation](https://nim-lang.org/docs/system.html#compiles,expr).


Re: Procedure which returns procedure

2017-04-04 Thread flyx
Your code does not work because you are using `func` as identifier, which is a 
reserved keyword. I demangled it a bit and renamed `func` to `fun`:


type
  MyProc1 = proc()
  MyProc2 = proc(p: MyProc1)
  MyProc3 = proc(p: MyProc1): MyProc1

proc applyAllSync(funcs: seq[MyProc2], onAllDone: MyProc1) =
  fold(funcs,
   proc(onDoneNothing: MyProc1) = onDoneNothing,
   proc(doBefore: MyProc3, fun: MyProc2) =
 return (proc(onDone: MyProc1): MyProc1 =
return doBefore(proc() =
  fun(onDone)
)
 )(onAllDone)()
  )



Re: Procedure which returns procedure

2017-04-04 Thread flyx
Your JS is horrible to read as it lacks type information (what is funcs, what 
is onAllDone, what is doBefore etc). I tried to interpret it but gave up. You 
should rather explain what you want to do than giving us this piece of code.


Re: Procedure which returns procedure

2017-03-31 Thread flyx
Try:


proc pprint[T1](ann: string): (proc(t0: T1): T1) =
  return proc(val: T1): T1 =
 return val

echo pprint[int]("test")(42)



Re: Alternative comment syntax

2017-03-31 Thread flyx
@hcorion This is Neo2 (it states that itself) and it is an image for printing 
and gluing on the keys. Therefore, there are multiple meta-key images to choose 
from.


Re: Alternative comment syntax

2017-03-30 Thread flyx
> One key # is found only in UK and Ireland a far as I know.

Germany…

> Any keyboard, any standard, with numeric keypad, has + - * and /.

So moving your hand over to the numpad and back is faster than pressing two 
keys?

> Just need people to think more open minded and understand that "this feature" 
> adds much more than takes.

Ad hominem again. You assume that people who oppose your proposition are not 
„open minded“ (enough).

> To be true, it just adds.

So far, none of your arguments convinced me even a bit that this _adds_ 
anything beyond complexity.


Re: Alternative comment syntax

2017-03-30 Thread flyx
> No attacks against anyone

You called people

> pythonic purists

which is obviously referring to people rather than the issue itself.

> I have no problems.

Your previous posts sounded differently.

> I want to help. Accept or deny.

Lacking commitment to discuss does not make your proposal look better.

> In my keyboard both '#' and '/' takes two keystrokes.

For the record, my keyboard has a one-key `#`, but `/` takes two keys. However, 
I don't use the standard keyboard layout anyway.


Re: Alternative comment syntax

2017-03-30 Thread flyx
> 1\. Many keyboards does not have an one key access to "#", > as the "/" key, 
> mine for instance, I usually need to look at alt-3 > or shift-3 combination.

Same is true for almost all other special characters which are used often in 
Nim, e.g.: `(`, `)`, `:`, `=`. I do not see how `#` is different from them.

> 2\. Most languages adopts a C++ like approach to use the one key "/" > found 
> in many US based keyboards.

So first you argue about _many keyboards_, but suddenly, because it fits your 
cause, the US layout is the important one? What about all the other layouts 
that don't have a `/` key (quite a lot don't)?

> 3\. People from Go, C++, Delphi, Rust, Xojo, Java, Javascript, Swift... > are 
> used to // double slash comments

People from Python, Scheme, Visual Basic, Bash, Ada, Haskell, Ruby... are not. 
Also, all those people are used to a different syntax than Nim has, so why, of 
all syntactic elements, should the comment syntax be kept?

> It just attracts more users, adds more fun, beautify the language, > and 
> makes more people feel at home.

Without presenting any evidence, this is just your personal opinion.

> I like the language, but I hate the "#" so much (as others)

So far, you are the only one who is complaining.

> and try to convince pythonic purists

This is ad hominem and therefore not a valid argument.

> there is a huge team of "//" lovers out there

As I said, I only see you complaining.

> Well, I consider this a bad preliminary choice, it's confusing clashing > 
> directly with the already diffused use of // everywhere.

_Everywhere_ in the sense of _every language you listed, ignoring all those 
that use different commenting styles_.

Your arguments are all bad and show that this is mostly an issue for yourself, 
because, as you state yourself, you hate `#` _so much_. Your points about 
keyboard layouts are not valid since you can simply change the keyboard layout. 
But instead of using tools that are more fit for the job, you urge others to 
fix your problems.


Re: Macro with runtime arguments

2017-03-22 Thread flyx
The macro will slurp `if debug: true else: false` as expression. It will not be 
resolved; instead, inside the macro, you will have this whole expression in 
your variable `debug`.

> Is there a way to 'extract' the boolean value of (the identifier) debug in 
> the macro

It does not have a value when the macro is executed. The macro is executed at 
compile-time. The `debug` in `main()` is a `let` variable, i.e. is set at 
run-time. The macro cannot possibly know its value when it executes, because it 
isn't set yet.

> The macro I'm messing with is the body of a loop that gets executed many 
> times; while I can make it a simple procedure, the performance goes down 
> considerably.

It seems like you want to use a simple template instead:


template dumbMacro(debug: bool = false): typed =
  if debug:
stderr.writeLine "DEBUG ON"
  echo "Hello from dumbMacro!"

proc main() =
  let debug = "-d" in commandLineParams()
  dumbMacro debug

when isMainModule:
  main()



Re: I compiled libui.dll file is not successful

2017-03-21 Thread flyx
By the way, you can check dependencies of your DLL with


dumpbin.exe /dependents libui.dll


(given that you have Visual Studio installed; it's in the VC bin folder)


Re: I compiled libui.dll file is not successful

2017-03-21 Thread flyx
> You may doubt that, but when run my Windows application alongside my "old" 
> libui.dll, the GUI program runs fine.

That may be because it requires a version of MSVCP**.dll which is available on 
your system. Or yes, because it has been statically linked into it.

> Do you know a good source where I could download MSVCP140.dll as standalone 
> file?

It is included in the linked installer. I would never download it anywhere else 
than from Microsoft itself – there are versions available on shady sites. You 
may succeed in opening the installer with 7zip or something on Windows. 
Otherwise, you need a minimal Windows VM, install it there, and then fetch the 
file.


Re: I compiled libui.dll file is not successful

2017-03-21 Thread flyx
> But I have a version of libui.dll (linked above), which does not have this 
> dependency and runs fine

I highly doubt it. The MSVCP140.dll is the C/C++ standard library on Windows, 
and almost every C/C++ program depends on it. Typically, Windows has some 
version(s) of this dll already preinstalled, in which case you do not need to 
redistribute it – it just works. However, when other versions are required than 
those that are present, you need to either bundle them or require the user to 
install them.


Re: I compiled libui.dll file is not successful

2017-03-21 Thread flyx
Well there are a lot of programs which just bundle MSVCP140.dll with their 
executable, like you do with libui.dll. So why not just place MSVCP140.dll next 
to it?

> It's also possible to directly install redistributable Visual C++ DLLs in the 
> application local folder, which is the folder that contains your executable 
> application file.

(From [here](https://msdn.microsoft.com/en-us/library/ms235299.aspx))


Re: Macro with runtime arguments

2017-03-21 Thread flyx
`debug` is an identifier and does not have a `boolVal`. You want to have 
`dumbMacro true` instead of `dumbMacro debug`.


Re: I compiled libui.dll file is not successful

2017-03-21 Thread flyx
> complaining about a missing MSVCP140.dll

So why don't you just 
[download](https://www.microsoft.com/en-gb/download/details.aspx?id=48145) and 
install it?


Re: Canonical idiom for opening files?

2017-03-14 Thread flyx
For ensuring file closing:


var fh = open(filename)
defer close(fh) # close fh at the end of current block
process(fh)


Encoding is not part of the file opening process in Nim. A file is just read 
byte for byte. If, for example, you want to open a latin-1 file and get a UTF-8 
string, you could do this:


import encodings
var content = convert(readAll(filename), srcEncoding="ISO-8859-1")


Note that I am using `readAll` which opens and closes the file automatically. 
You can also use the method shown above, instantiate an `EncodingConverter` and 
then read and convert each line / character / whatever individually.


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: Chocolatey Package for Nim?

2017-01-28 Thread flyx
With the same argument, it would also be necessary for Nim to have an official 
package for debian, Fedora, Arch, Nix, Homebrew…

I think maintaining packages is in better hands with those people who use the 
package managers.


Re: Forum rules

2017-01-26 Thread flyx
There are no official rules. There have been threads about having a CoC and the 
majority was against it. General opinion usually is _„instead of thinking about 
rules, just write some Nim code“_. There also isn't some big sign on your front 
door which tells you how to behave while out on the street, yet people get 
along with each other most of the time.


Re: Return SUM types from proc

2017-01-25 Thread flyx
> Regarding pointers being the only option for polymorphic returns; I guess 
> this depends on the object layout used? For instance, I assume object variant 
> does not need to be same size but still allows polymorphism in return value, 
> simply by reserving space for the biggest variant in the calling stackfram.

Object variants are not polymorphism (at least not in the computer science 
semantics of the word). But you are right, it works because it reserves the 
size of the largest possible variant. One obvious difference to polymorphism is 
that whoever defines the object type has complete control over any variants. 
With polymorphism, a user of your type can define a new subtype. This is why 
using `if v of SomeType` is bad style – you cannot know all derived types, 
because other code using your code may define new derived types.


Re: Return SUM types from proc

2017-01-25 Thread flyx
Generally speaking, whenever you are using `if v of SomeType`, you are holding 
it wrong. Polymorphism gives you the power of defining dispatching methods for 
operations whose implementation differs based on which subtype your variable 
holds.

If implementing your code with dispatching methods seems clumsy or simply does 
not fit your coding style, use object variants instead. The question of whether 
the values should reside on the stack or on the heap is a different one. For 
example, [JsonNode](http://nim-lang.org/docs/json.html#JsonNode) is an object 
with variants but also a `ref` type residing on the heap.


Re: Return SUM types from proc

2017-01-25 Thread flyx
References (or pointers) are a prerequisite for runtime polymorphism since they 
are the only way to have differently typed values fit into the same memory 
location, since all pointers have the same size. Might not be true for all 
languages.


Re: Return SUM types from proc

2017-01-25 Thread flyx
`A or B` needs to be collapsed to one definite type at compile time. It is 
typically used for parameter types where the compiler sees which type is given 
at the calling site. This is not applicable if you want your return values to 
have different types at runtime.

There are multiple solutions. First solution is derived types:


type
  Base = ref object of RootObj
  
  A = ref object of Base
a_value: int
  
  B = ref object of Base
b_value: int

proc test(arg: int): Base =
  if arg < 0: return A(a_value: arg)
  else:   return B(b_value: arg)

let a = test(10)
let b = test(-5)


Another solution is object variants:


type
  RetKind = enum
A, B
  
  Ret = object
case kind: RetKind
of A: a_value: int
of B: b_value: int

proc test(arg: int): Ret =
  if arg < 0: return Ret(kind: A, a_value: arg)
  else:   return Ret(kind: B, b_value: arg)

let a = test(10)
let b = test(-5)



Re: var param vs tuple as return value

2017-01-25 Thread flyx
Well there's a [nim](http://stackoverflow.com/questions/tagged/nim) tag on 
StackOverflow. It certainly wouldn't harm if Nim had more exposure there. I 
think this forum should be more for discussions which do not fit into SO's Q&A 
format.


Re: How to understand pragmas in Nim?

2017-01-24 Thread flyx

proc compile(code: string): {.compileTime.} NimNode =


This is a syntax error because the proper syntax would be:


proc compile(code: string): NimNode {.compileTime.} =


Partly related: Ada is in a similar state. In the rationale of Ada 83, pragmas 
were described as having _no influence on the meaning of the program_. Then, 
Ada 95 came along and used pragmas for all sorts of things, including some 
which changed the meaning of the code.

For Ada 2012, a solution was sought and found; it was a new part of the syntax 
named _aspects_. So, instead of this:


procedure Flush;
pragma Import (StdCall, Flush, "glFlush");


You could now write


procedure Flush with
  Import => True, Convention => StdCall, External_Name => "glFlush";


This is pretty close to how Nim pragmas already work, as they can already be 
tied to some entity instead of being standalone. For me, the concept seems to 
be closer to aspects than to traditional pragmas.

C# and Java have attributes/annotations which _have_ to be bound to some 
entity. They are also part of the reflection descriptors, so they are pretty 
different from what traditionally is called a pragma. However, some still have 
the concept of being a hint to the compiler (for example, @Synchronized in 
Java).

To summarize: Pragmas in a language are semantically placed on an axis 
somewhere between „compiler hints“ and „part of the language semantics“. The 
trend seems to be towards the latter, but the word _pragma_ is usually bound to 
the former, so some languages call them differently. Nim calls them pragmas but 
also supports the annotation/aspect semantics, and enables users to define „new 
pragmas“ via macros. Which is conceptually not very different to what C# and 
Java do, it is only much more powerful because the semantics can be given in 
the macro implementation, while in Java, the semantics of an Annotation is 
defined somewhere else.


Re: No way to run my code, idk how to force a float as an Int

2017-01-23 Thread flyx
This happens because `/` on ints returns a float. You want to use `div` 
instead, which is integer division.


var maxLignes = ((nombreDePyramides + 2) * (nombreDePyramides + 3)) div 2 - 
4


Or, alternatively, convert it – this is clearly the inferior solution, but 
given here for completeness:


var maxLignes = int((nombreDePyramides+2)*(nombreDePyramides+3)/2-4)


In both cases, you do not need to give the type because it is derived from the 
expression.


Re: Nim VFS (virtual file system)

2017-01-16 Thread flyx
Some thoughts:

The idea seems to be basically what Java does with `*.jar` files. And you say 
Tcl also does it. So why can they do this? They can because running both a Java 
application and a Tcl script requires a runtime environment (Tcl interpreter / 
JRE) on the target machine. So if the user must install this runtime 
environment anyway, it is minimal pain to add such a VFS to it.

Nim, on the other hand, does not depend on a special runtime environment (no 
more than C applications, anyway). So providing Nim artifacts in the form of a 
VFS would suddenly require users of Nim applications to install an additional 
tool. This is clearly an inconvenience and the question is whether the benefits 
of this VFS amortize this inconvenience.

In contrast to Java, Nim libraries are usually compiled into the application. I 
have never seen a Nim lib that is dynamically linked to other Nim code. So for 
libraries, the source code is distributed. This will, of course, not always be 
the case – when a Nim library requires non-code resource files on its own, it 
will need a way to tell an application that it needs those files. This is where 
a VFS approach may come in handy. Resources are usually necessary for GUI 
libraries, which is a special case, but also may be useful for things like 
i18n. So we may need a more sophisticated approach for including libraries than 
just `nimble install`.

But this can all be done at compile time with a bundling script. I think the 
better thing to have would be a bundler that can build native bundles for 
common target platforms, like an `.app` bundle for macOS, a `.deb` / `.rpm` 
package for some Linux distributions and an installer for Windows. This bundler 
would also have a minimal API for platform-independent access to application 
resources (which will be put in `/usr/share` on Linux, but inside the app 
bundle / installation directory in macOS / Windows).

So, basically, I am suggesting that an API that emulates some kind of VFS would 
be good but the backend should be the application resource management native to 
the target system instead of some zipped file.


Re: Please , can we stop spams?

2016-12-23 Thread flyx
Having a GitHub account should not be required to participate in the community 
and I think it's harmful to make people with few original Nim code second-class 
citizens.


Re: Return values question

2016-12-13 Thread flyx
Interesting. I only remember that Araq once explained that strings and seqs are 
heap objects managed by the garbage collector, but I may have misunderstood it. 
In any case, there should be some official documentation about this.


Re: Return values question

2016-12-13 Thread flyx
> When a shallow sequence is resized, only the variable currently being 
> modified has its reference updated; the other variables will still have 
> references to the old data.


proc foo() =
  var a = newSeqOfCap[int](2)
  a.add(1)
  var b: seq[int]
  shallowCopy(b, a)
  a[0] = 0 # modify sequence after copying
  a.add(2) # further modification
  echo a
  echo b
  b.add(3) # resizing happening here!
  echo a
  echo b

foo()


This outputs:


@[0, 2]
@[0, 2]
@[0, 2, 3]
@[0, 2, 3]


Modifications after shallow copying are fine because strings and seqs are 
garbage-collected heap-objects. As you see, both references are still fine 
after resizing happened.


Re: Newyear is coming , is 2017 the year for nim?

2016-12-10 Thread flyx
I have heard that 2017 will already be the year of Linux on the desktop, so Nim 
might have to wait one more year.


Re: Using Nimscript as an embedded scripting language?

2016-12-05 Thread flyx
> Is it possible to use Nimscript as an embedded scripting language

In theory: Yes, of course. Why shouldn't it?

In practice: Since the compiler and the standard library are rather modular, 
you can include parts of it in your project. However, there is no API dedicated 
to what you want to do, so you would need to extend and modify quite a bit of 
the current code.

I believe that Lua's API for embedding the interpreter would still be superior 
as it was designed with embedding in mind. Not mentioning the restrictions of 
Nim's VM (for example, using `ref` variables is still buggy). Lua's embedding 
API is also designed for safety as you can tightly control which parts of the 
standard library will be available. It would be a lot of work to reimplement 
that for Nim – for example, you would need to split up the `system` module 
since it contains a lot of stuff you may not want to make available (like File 
I/O), while other things are absolutely necessary (basic types and procs, e.g. 
for strings, arrays and seqs).


Re: Same line versus single-line block in the AST

2016-11-28 Thread flyx
> And usually there are no parts in the AST that are "always" there to always 
> ignore

Well that's good to know :). I wrongly assumed by testing that the `RecList` 
will always be there.


Same line versus single-line block in the AST

2016-11-28 Thread flyx
Consider this code:


import macros

dumpTree:
  type
ObjectKind = enum
  oA, oB

ObjectType = object
  case kind: ObjectKind
  of oA:
a: string
  of oB:
b: string

ObjectType2 = object
  case kind: ObjectKind
  of oA: a: string
  of oB: b: string
  
  proc foo(): int = 2
  proc bar(): int =
2


It outputs:


StmtList
  TypeSection
TypeDef
  Ident !"ObjectKind"
  Empty
  EnumTy
Empty
Ident !"oA"
Ident !"oB"
TypeDef
  Ident !"ObjectType"
  Empty
  ObjectTy
Empty
Empty
RecList
  RecCase
IdentDefs
  Ident !"kind"
  Ident !"ObjectKind"
  Empty
OfBranch
  Ident !"oA"
  RecList
IdentDefs
  Ident !"a"
  Ident !"string"
  Empty
OfBranch
  Ident !"oB"
  RecList
IdentDefs
  Ident !"b"
  Ident !"string"
  Empty
TypeDef
  Ident !"ObjectType2"
  Empty
  ObjectTy
Empty
Empty
RecList
  RecCase
IdentDefs
  Ident !"kind"
  Ident !"ObjectKind"
  Empty
OfBranch
  Ident !"oA"
  IdentDefs
Ident !"a"
Ident !"string"
Empty
OfBranch
  Ident !"oB"
  IdentDefs
Ident !"b"
Ident !"string"
Empty
  ProcDef
Ident !"foo"
Empty
Empty
FormalParams
  Ident !"int"
Empty
Empty
StmtList
  IntLit 2
  ProcDef
Ident !"bar"
Empty
Empty
FormalParams
  Ident !"int"
Empty
Empty
StmtList
  IntLit 2


As you can see, the declaration of `ObjectType` produces `RecList` s inside its 
case branches, while `ObjectType2` does not. I think it would be good for both 
cases to produce the same AST since they are equivalent.

As comparison, I added the two proc defs at the end: Both produce a wrapping 
`StmtList` although one has its implementation on the same line and one in the 
next line.

My problem is that a specification of how the AST will look like exactly is 
currently missing, so I usually just look at the AST that is produced. And that 
way, I may overlook things like „if a variable declaration is on the same line 
as the of branch, no wrapping `RecList` is produced“.


Re: NimYAML 0.7.0 released

2016-11-28 Thread flyx
`loadToJson` ignores tags because the JSON structures do not know anything 
about tags. You have several options:

**Using the serialization API with an implicit variant object**

First, you need to define the type for the tag `!remote`. You need to tell 
NimYAML how to load that type. Then, you define a variant object type that can 
hold either normal strings or `!remote` values. You then tell NimYAML to treat 
this variant object type implicitly for loading the chapters. Example code:


import yaml.serialization, yaml.taglib

type
  Remote = distinct string
  ChapterKind = enum
ckLocal, ckRemote
  Chapter = object
case kind: ChapterKind
of ckLocal:
  lValue: string
of ckRemote:
  rValue: Remote
  Root = object
chapters: seq[Chapter]

proc constructObject*(s: var YamlStream, c: ConstructionContext,
  result: var Remote) =
  # construct a Remote like a string
  constructObject(s, c, string(result))

setTagUri(Remote, "!remote")
markAsImplicit(Chapter)

var root: Root
load("""
chapters:
  - foo
  - bar
  - !remote http://example.com/somefile
""", root)

echo "Parsed chapters:"
for c in root.chapters:
  case c.kind
  of ckLocal: echo "[Local] ", c.lValue
  of ckRemote: echo "[Remote] ", string(c.rValue)


Sadly, you cannot simply transform the chapter values into some `tuple[value: 
String, remote: bool]` because NimYAML's serialization API uses tags to denote 
types, not annotations.

**Using the DOM API**

Perhaps simpler for simple use cases:


import yaml.dom

var document = loadDOM("""
chapters:
- foo
- bar
- !remote http://example.com/somefile
""")

echo "Parsed chapters:"
for c in document.root.pairs[0].value.children:
  echo if c.tag == "!remote": "[Remote] " else: "[Local] ", c.content


The DOM API needs some love; currently mappings are parsed into a 
`seq[tuple[key, value: YamlNode]]` which is not ideal for accessing specific 
subtrees. A Table would make more sense. Pull requests are welcome :).

**Using the sequential API**

This may be useful for use cases where you need to process the input 
sequentially since it doesn't load everything in an object and therefore is 
faster:


import yaml.parser, yaml.taglib, yaml.stream

var
  myTagLib = initCoreTagLibrary()
  yTagRemote = myTagLib.registerUri("!remote")
  p = newYamlParser(myTagLib)
  events = p.parse("""
chapters:
  - foo
  - bar
  - !remote http://example.com/somefile
""")

doAssert events.next().kind == yamlStartDoc
doAssert events.next().kind == yamlStartMap
let key = events.next()
doAssert key.kind == yamlScalar
doAssert key.scalarContent == "chapters"
doAssert events.next().kind == yamlStartSeq
var cur = events.next()
echo "Parsed chapters:"
while cur.kind != yamlEndSeq:
  doAssert cur.kind == yamlScalar
  echo if cur.scalarTag == yTagRemote: "[Remote] " else: "[Local] ", 
cur.scalarContent
  cur = events.next()
doAssert events.next().kind == yamlEndMap
doAssert events.next().kind == yamlEndDoc
doAssert events.finished()




Re: noob: json to object conversion

2016-11-26 Thread flyx
Since YAML is a superset of JSON, you can use 
[NimYAML](http://forum.nim-lang.org///nimyaml.org) to deserialize the JSON 
file. It is able to automatically map a JSON object to a Nim object:


import yaml.serialization, streams

type Config = object
  rootDev: string
  grubDevLabel: string
  title: string
  updateGrubDir: string

proc readConfig(): Config =
  var s = newStringStream("""
{
  "rootDev": "rootDevValue",
  "grubDevLabel": "gdlValue",
  "title": "titleValue",
  "updateGrubDir": "ugdValue"
}
  """)
  load(s, result)

let config = readConfig()


To load a file, simply use a `FileStream` instead of a `StringStream`. Note 
that the names of the object's fields must match exactly.


Re: nim4Android

2016-11-10 Thread flyx
Wouldn't it make more sense to bind Nim to Android NDK? I think you would have 
a hard time to call Android UI libs through jnim, unless you provide a thick 
layer. There is also 
[NativeActivity](https://developer.android.com/reference/android/app/NativeActivity.html)
 which enables you to write purely native apps.


Re: NimYAML 0.7.0 released

2016-11-08 Thread flyx
NimYAML 0.8.0 is now available. Its focus was on making it more capable of 
being used for configuration files:

  * You can now set default values of object fields with `setDefaultValue`.
  * You can now mark object fields as transient with `markAsTransient` so that 
they are not serialized or expected in YAML input.
  * You can now ignore input keys with `ignoreInputKey`. This makes it easier 
to parse YAML input that contains data which is not of interest.



Moreover, timestamps can now be parsed into `Time` values. However, this is 
only usable with most recent Nim devel version, since timezones are broken in 
0.15.2. 


Re: Generic openarray param

2016-10-28 Thread flyx
I wonder why this fails:


type
  Iterable = concept c
for i in c: discard

proc test[T](x: T) =
  echo x

proc test(x: Iterable) =
  for i in x: echo i

test(1)
test([1, 2, 3])


Shouldn't `Iterable` be a better match?


Re: What is "Metaprogramming" paradigm is used for?

2016-10-22 Thread flyx
I explained some basic metaprogramming stuff in my [article on 
NimYAML](https://flyx.org/2016/09/22/nimyaml/). Actually, 
[NimYAML](http://forum.nim-lang.org///nimyaml.org) as a whole is a good example 
of metaprogramming usage, because what is does is not doable in most other 
languages (though some „cheat“ by using reflection, which is inferior).

[emerald](http://forum.nim-lang.org///flyx.github.io/emerald/) is another 
project of mine which makes extensive use of metaprogramming. Actually, I 
initially wrote that to test Nim's metaprogramming capabilities.

For snippets, a template usually suffices, you do not need macros for that. It 
is important to recognize when you do _not_ need macros. The actual use-cases 
for macros are rather rare, because you should always use the least powerful 
tool that can do the job, and that mostly boils down to generics and/or 
templates even for complex problems.


Re: Macro: enumerate exported functions from a module

2016-10-21 Thread flyx
Wow, I never thought of that. With this, we can write 
[fuckit.nim](https://github.com/ajalt/fuckitpy)!


Re: Macro: enumerate exported functions from a module

2016-10-21 Thread flyx
If you write the module yourself, the simplest way would be:


macro myMacro(body: typed): typed =
  # do things here
  #
  # do not forget to add the original procs to the output!

myMacro:
  proc proc1*() = discard
  proc proc2*() = discard
  
  # ...



Re: Markdown parser

2016-10-20 Thread flyx
The Nim compiler has the `rst2html` action which transforms a reStructuredText 
file to HTML. It can do everything Markdown can, plus some extras (e.g. Nim 
syntax highlighting). By default, it uses the same HTML template which is being 
used for generating API documentation (with `nim doc` / `nim doc2`), but you 
can customize it with a `nimdoc.cfg`. This is somewhat documented 
[here](http://forum.nim-lang.org///nim-lang.org/docs/docgen.html).

The rST implementation is also usable as package from Nim code, as documented 
[here](http://forum.nim-lang.org///nim-lang.org/docs/rst.html). This forum uses 
rST as input format for posts.


Re: Is there anyway to change the NimNode(stmt) to string?not the ast format

2016-10-13 Thread flyx
node.repr


Re: problem when use lua bind

2016-10-13 Thread flyx

var p = cast[ptr fuck](L.newuserdata(sizeof(fuck).cint))


You allocate memory which is **not zeroed**. So its content may change 
depending on what it was used for beforehand.


echo repr(p)


Now you want a representation of that memory. `p.ud` may have any value here. 
If it is not `nil`, `repr` will try to resolve it to give you a representation 
of its content. What happens is that after those `echo` s, `p.ud` contains some 
garbage and `repr` tries to interpret that as a pointer and follows it, 
resulting in a SIGSEGV.

So just move the `echo repr(p)` line after `p.ud = new(test2)`.


Re: Performance of fastRows at module db_sqlite

2016-10-09 Thread flyx
Yes, Stefan's solution is somewhat nicer, didn't think about that. If there is 
more data involved, split may be further accelerated by setting `maxsplit`:


let (lookup_id, lookup_name_source) = p.rowEntry(col).split('|', 2)[0..1]



Re: Performance of fastRows at module db_sqlite

2016-10-09 Thread flyx
I cannot really answer the question whether there are missed optimization 
opportunities in Nim's SQLite wrapper, but being a wrapper, it sounds unlikely.

There are some things about your code I can comment on:


lookup_id = p.rowEntry(col).split('|')[0]
lookup_name_source = p.rowEntry(col).split('|')[1].toUpperAscii()


This is inefficient because you are splitting the string multiple times. You 
can do this instead:


let colContent = p.rowEntry(col).split('|')
template lookup_id(): untyped = colContent[0]
template lookup_name_source(): untyped = colContent[1]


But that concerns the CSV and should not be much of a performance hog (unless 
your CSV is very large).

Now the actual part where you could use optimization are these lines:


for row in mydb.fastRows(sql"select count(*) from tb_reference_pj where 
company match ?", (lookup_name_source)):
  if row[0] != "":


What are they for? the result will never be `""`, because `count(*)` always 
returns some number (correct me if I'm wrong, I haven't done SQL for some 
time). You are issuing a potentially expensive query here for no reason.

Onto the next query:


for r in mydb.fastRows(sql"select * from tb_reference_pj where company 
match ?", (lookup_name_source)):


You are querying every column value from a table although you are using only 
one value afterwards. Okay, to be fair, the following lines are probably not 
your actual code, right? Note that if you did the template thing I showed, you 
have to use `lookup_name_source()` here.

Your code would probably be faster by just removing the first query.


Re: Nim code to Remove Accented Letters

2016-10-03 Thread flyx
Here is how you can do it with premature optimization:


import unicode, strutils

proc translationTable(src, dest: string): array[0x1f00, char] 
{.compileTime.} =
  for i in 0..<0x1f00: result[i] = '\0'
  var
srcIndex = 0
destIndex = 0
  while srcIndex < src.len and destIndex < dest.len:
let srcCh = src.runeAt(srcIndex)
if srcCh.int32 >= 0x1f00:
  echo "Cannot translate this character: " & escape(srcCh.toUTF8())
  quit(1)
let destCh = dest.runeAt(destIndex)
if destCh.int32 >= 0xff:
  echo "Cannot translate to non-ASCII character: " & 
escape(destCh.toUTF8())
result[srcCh.int] = destCh.char
srcIndex.inc(src.runeLenAt(srcIndex))
destIndex.inc(dest.runeLenAt(destIndex))

proc translate(input: string): string =
  const ttable = translationTable("ÁÀÃÂÇáàãâçÉÊéêÍíÑÓÔÕñóôõÚÜúü",
  "CcEEeeIiNOOOnoooUUuu")
  result = newStringOfCap(input.len)
  var i = 0
  while i < input.len:
let r = input.runeAt(i)
let t = ttable[r.int]
i.inc(input.runeLenAt(i))
result.add(toUTF8(Rune(
(t.int8 == 0).int32 * r.int32 +
(t.int8 != 0).int32 * t.int32)))

echo translate("Cédille Français")


Points of interest:

  * Uses a table that translates unicode characters up to `0x1eff` to ASCII 
characters. This covers everything up to [Latin Extended 
Additional](https://en.wikipedia.org/wiki/Latin_Extended_Additional), and I 
don't believe there are characters beyond that that can meaningfully translated 
into ASCII characters (but YMMV).
  * Table is constructed at compile time and is not sparse, so it occupies some 
8KB regardless of how many characters you want to translate. On the other hand, 
there is no _contains_ check necessary which makes the code faster. This is 
probably only useful if you use the translation code many times during one run.
  * Implementation uses no branching except for the loop, so it's very fast.




Re: Nim Chess 2 with transposition table support is available

2016-10-03 Thread flyx
Your compilation instructions would probably be nicer if, instead of depending 
on absolute paths and symlinks, there would be a Makefile like this:


board: board.nim engine.nim
nim c -p:../nim-gio/src -p:../nim-atk/src -p:../nim-glib/src 
-p:../nim-gdk3/src -p:../nim-gtk3/src \
  -p:../nim-gtksourceview/src -p:../nim-gobject/src 
-p:../nim-cairo/src -p:../nim-cairo/src \
  -p:../nim-pango/src -p:../nim-pango/src -p:../nim-gdk_pixbuf/src 
board.nim


So that people can simply type


make board


I can compile it on OSX, but it fails to start with


could not load: libgobject-2.0.dylib


Not sure why it tries to load that since it is GTK3. Any advice?


NimYAML 0.7.0 released

2016-10-01 Thread flyx
Since we have Nim 0.15.0 now, NimYAML 0.7.0 follows. This list is relevant for 
upgrading from a previous version:

  * The API has been split over several modules. Importing the [base 
package](http://forum.nim-lang.org///flyx.github.io/NimYAML/yaml.html) imports 
all subpackages, so this change is backwards-compatible. However, you are 
encouraged to import only those parts of the API you need.
  * It is possible to call all loading procs with a `string` instead of a 
`Stream` input. Loading YAML directly from a string will enable NimYAML to 
include correct line content in its parsing exceptions. This is not always 
possible with using Streams, where it will return an empty string instead if 
the line content is not available.
  * The API for writing custom represent/construct procs has changed. 
[representObject](http://forum.nim-lang.org///flyx.github.io/NimYAML/serialization.html#representobject)
 does not return a `YamlStreamEvent` iterator anymore. Instead, the 
implementation shall put its generated event(s) into the 
`SerializationContext`. You have to update existing code if you use that 
functionality.



Major new features are:

  * The serialization API features better checks and error messages in case of 
invalid input. This makes NimYAML feasible for user-written configuration files.
  * Usage of first-class iterators has been removed to make compiling to JS 
possible. However, finishing this is still blocked by a Nim compiler bug, see 
[here](https://github.com/flyx/NimYAML/issues/24).
  * YAML compliance has been improved.



A complete list of changes is available 
[here](https://github.com/flyx/NimYAML/blob/devel/CHANGELOG.md). NimYAML 0.7.0 
requires Nim 0.15.0.


Re: about nimscript

2016-09-21 Thread flyx
What is _code_? An INI file also contains _code_, i.e. some text structure that 
complies with a grammar. You also need a parser to read it programmatically.

You may want to post some references about what's the problem with Python's 
setup.py, because from what you write, it doesn't seem obvious.


Re: Run tests

2016-09-15 Thread flyx
You can define any custom commands you want by putting them into `config.nims` 
at the root of your project. For example, this is what I have in NimYAML:


task tests, "Run all tests":
  --r
  --verbosity:0
  setCommand "c", "test/tests"


This basically tells Nim to execute `nim c -r --verbosity:0 test/tests` when I 
type in `nim tests`. If you want to run tests in multiple files with one 
command, you can do:


task tests, "Run all tests":
  exec r"nim c -r someFile"
  exec r"nim c -r anotherFile"
  setCommand "nop"



Re: Unable to parse JSON Payload

2016-09-15 Thread flyx
`application/json` is not a supported enctype in HTML. See [MDN 
documentation](https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/enctype).
 There was a [proposal](https://www.w3.org/TR/html-json-forms/) for it - note 
the giant yellow-dotted banner there. It is not actively maintained and as far 
as I know, no browser supports it. So your problem is more on the client-side 
than on the server-side. But even if browsers would support it, this would need 
to be implemented in Jester, because when the parameters reach your own code, 
the request has already been parsed.

To sum up: Not possible because neither supported on the client nor on the 
server side. Review your requirements.


Re: Getting captures from PEGS match

2016-09-12 Thread flyx
> This will work if I use @["", ""] instead, but I don't see why I have to?

Because `match` takes an `openarray[string]` for `matches`. It means that the 
proc works with both an array and a seq. And an array cannot be extended.

Since the number of matches in your PEG is statically known, it simply does not 
make sense to use a seq. Just use an array instead:


var matches: array[0..1, string]



Re: Deployment story for Nim

2016-09-12 Thread flyx
> would the executable be usable in other machines with the same operating 
> system?

In general, yes.

> Is it standalone?

Depends on your definition of standalone, I guess. For a simple test 
executable, `ldd` yields:


linux-vdso.so.1 =>  (0x7fff641ee000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x7f0bee51c000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x7f0bee153000)
/lib64/ld-linux-x86-64.so.2 (0x564a0afb9000)


So apart from the kernel and libc, there are no dependencies. This will of 
course change when you use non-pure Nim libraries (i.e. libraries that link to 
a C library). But if your question is whether the executable requires a 
fully-blown runtime environment (like e.g. JVM or .NET), then the answer is 
_no_.

> What is the standard way to package Nim applications?

For source distribution, Nimble. For binary distribution, there is no standard 
way, since this is very OS-dependent. I guess the sensible way to do it is „use 
whatever package manager the target OS uses“. Some people like Docker and use 
that; Nim itself has an official Docker image.


Re: Is this a compiler bug?

2016-09-09 Thread flyx
I agree that it would be able to determine wether this is a proc call or a type 
conversion from the parameter type. This can be a feature request.

It is probably not so simple to issue a warning with such conflicts, because 
the type may be defined in one module, the proc in another module, and both get 
imported to a third module.


Re: Is this a compiler bug?

2016-09-09 Thread flyx
Where would the compiler bug be?

You define a proc named `int`, so when encountering `int(k)`, the compiler 
tries to call this proc instead of doing a type conversion. I'd say, it behaves 
as expected.

Since types are not keywords in Nim, it is not per se illegal to name a proc 
`int`.


Re: International Keyboard Setting not mapping correctly in Aporia under Windows

2016-09-08 Thread flyx
Partly related: I know that GTK's support for Keyboard layouts on Windows is 
rather broken, because they do not use the API as they should. This has forever 
been a problem with the Neo layout I use for typing. It is no problem on OSX or 
Linux. GTK devs marked this issue as _wontfix_. But I am not sure if it is the 
same problem you encounter.


Re: The cstring type and interfacing with the backend.

2016-09-01 Thread flyx
> Everything is split more explicitly, and there is no system wide hybrid type 
> that has to be compatible with whatever the backend is.

So, one cstring for `char*`, one for `std::string`, one for `NSString` and one 
for JS' `string`? That looks like an awful lot of string types.


Re: Nim doc page broken

2016-08-31 Thread flyx
I created a pull request that fixes this: 
[https://github.com/nim-lang/packages/pull/408](https://github.com/nim-lang/packages/pull/408)


Re: Where do I learn how to program Nim without a GC?

2016-08-25 Thread flyx
> I mean somehow I have to tell Nim when to free memory right?

Yeah sure, you just use these: 
[alloc](http://forum.nim-lang.org///nim-lang.org/docs/system.html#alloc,Natural),
 
[dealloc](http://forum.nim-lang.org///nim-lang.org/docs/system.html#dealloc,pointer),
 
[allocShared](http://forum.nim-lang.org///nim-lang.org/docs/system.html#allocShared,Natural),
 
[deallocShared](http://forum.nim-lang.org///nim-lang.org/docs/system.html#deallocShared,pointer).
 You can cast the `pointer` from and to 
[ptr](http://forum.nim-lang.org///nim-lang.org/docs/system.html#ptr) types and 
then you have your manually managed heap memory.

(This is a general answer to how to use non-GC'd memory and has nothing to do 
with memory regions)


Re: Strange GC problem ?

2016-08-23 Thread flyx
Yeah, if `ref array` does not work properly, it should indeed produce a 
compiler error. You should file a GitHub issue.


Re: dynamically creating a tuple

2016-08-22 Thread flyx
As I said, you cannot create a _dynamic_ tuple. The tuple type must be fixed at 
compile time.

I believe you will get better answers if you show example code with an input 
sequence, and expected output. For me, it is still rather unclear what you are 
trying to achieve, because when you have a sequence of (int, string) tuples, 
you already have the tuples you want in there.


Re: dynamically creating a tuple

2016-08-22 Thread flyx
You cannot have `10` and `'a'` in the same sequence. `10` is an `int`, `'a'` is 
a `char`.


Re: dynamically creating a tuple

2016-08-22 Thread flyx
It is not clear what exactly you are trying to accomplish.


d = (b: 10, c: "cd")


This already creates a tuple and is not a sequence. How does the sequence you 
talk about look? Since the tuple needs one `int` and one `string`, you would 
not only need to map the sequence items to tuple fields, but also store `b` as 
string (or `c` as int if feasible...), because a sequence cannot contain 
different types.

What you want to do is probably possible with a simple generic proc and 
[fields](http://forum.nim-lang.org///nim-lang.org/docs/system.html#fields.i,T) 
or 
[fieldPairs](http://forum.nim-lang.org///nim-lang.org/docs/system.html#fieldPairs.i,T).
 However:

  * The transformation would still be static and not dynamic, because you have 
to give the tuple's type at compile time.
  * Talking about _dynamically creating a tuple_ hints to a misunderstanding of 
the purpose of the tuple within Nim's typing system. Transformation between a 
tuple and a sequence would typically only make sense for data serialization and 
should be avoided otherwise.




Re: Documentation colour theme

2016-08-21 Thread flyx
The text I quoted said _consider_. Not _do not use black_. The author 
considered it and decided to use both black and dark gray text (see the text in 
the margin and the footer?).


Re: Documentation colour theme

2016-08-21 Thread flyx
Another opinion on text color from 
[here](http://forum.nim-lang.org///practicaltypography.com/color.html):

> But con­sider mak­ing body text on screen dark gray rather than black. 
> Screens have more se­vere con­trast than pa­per, and thus are more tir­ing to 
> read at full con­trast. This is be­cause screens pro­duce color by emit­ting 
> light di­rectly, whereas pa­per pro­duces color by ab­sorb­ing and 
> re­flect­ing am­bi­ent light.

I would also prefer text color to be a bit darker. But black is overkill.


Re: Going to Haxe. Nim In Action book available.

2016-08-15 Thread flyx
> I have yet to seen a single example of anybody using namespacing in 
> functional programming. Then again, its relative "new" in PHP. rofl

PHP is all but a functional programming language. I think you are confusing 
terms here, _functional_ programming languages are things like Haskell, Scheme 
or (to a lesser extent) LISP. Others provide some functional features in 
addition to imperative programming.

There are lots of programming languages which provide namespaces without being 
necessarily OOP. Nim itself uses namespaces, which map to filenames (like 
Python does). Ada has a package system which is the most feature-rich namespace 
implementation ever, without forcing the user to do OOP. Go uses directories as 
namespaces.

> Yada yada yada ... typical forum bully tactics.

I have just answered to your arguments in a critical, but neutral way. This is 
quite the opposite of _forum bully tactics_, which include, amongst others, [ad 
hominem](https://en.wikipedia.org/wiki/Ad_hominem) tactics (like, for example, 
calling another user a _forum bully_).

> Lets all wast hours fighting it out on a forum so one of use can both feel 
> superior.

This is not and was never my intent. Where do you deduce this from? Because I 
criticized your arguments? This is what a discussion is for. If you do not want 
to discuss, there is no point in answering here.

> There is always somebody who gets pissed or disagrees and then wants to wast 
> hours discussing something that will not change both parties there opinion 
> anyway.

I am not pissed. You seem to be. You even state that later in your post.

> Bullshit first class. If you can not tell the different between a piece of 
> OOP & FP code, then you really do not need to start arguing about it. Feeling 
> superior yet?

As I said, you seem to confuse the term _functional programming_ with 
_imperative, procedural, non-OOP programming_. I do not want to continue this 
discussion on a level where you just rely on personal attacks, thanks.


Re: Going to Haxe. Nim In Action book available.

2016-08-14 Thread flyx
> Is this implying that sufficiently large codebase of any other (or of a 
> specific programming language) would look any better? I don't think so, but 
> i'd like to hear about that.

Almost all codebases of large applications look awful. There are a lot of 
reasons for that other than programming paradigms used. I do not want to claim 
that some would look better without OOP. I simply wanted to state that I had a 
look at a lot of code bases through the years in order to find evidence of how 
OOP would lead to cleaner code, and I have yet failed to find any.


Re: Going to Haxe. Nim In Action book available.

2016-08-14 Thread flyx
> In general object oriented programming results in a more clean code base ( 
> example ).

Have you ever seen any codebase of a sufficiently large Java 
library/application? I have yet to see _one_ example where OOP lead to a 
cleaner code base. [This image is usually a pretty accurate description of an 
OOP codebase](http://forum.nim-lang.org///imgur.com/Q0vFcHd).

> Personally i do not understand why people still insist on functional 
> programming.

Nobody suggested functional programming.

> Both do the same in this simple example.

And none is functional.

> But as one starts to extend functionality, its where you are much more likely 
> to run into conflicts ( forcing the need for instance to namespace ).

Namespaces have nothing to do with object orientation. You can perfectly use 
namespaces in non-OOP languages.

> Of the two examples, what is more easy to extend ( inherit, override, 
> abstract, etc ) and clean. Its simply the object oriented version.

So you show some OOP code, then you show some imperative, non-OOP code, and 
then you ask which is more easy to _inherit_, _override_, make _abstract_? 
Well, those are all things you do in OOP languages, and you just assume that 
this is useful and needed without providing any evidence for it. So tell me: 
How would you want to extend a _round_ function, so that OOP becomes useful? 
The only useful extension is to be able to use it on other types than just 
`float` \- and that can easily be done with generics and without OOP.

And um, calling this messy `class Main {` stuff _clean_ is… nothing I would do.

> If we simply look at GoLang with its forced function paradigm, it still 
> relies on C like function attachment to objects.

Go is not functional, it is imperative. I also do not understand what exactly 
you mean by „C like function attachment to objects“. You seem to assume that it 
is necessary to attach functions to objects, without providing any evidence for 
it.

> Nim really focuses more to Python developers. Where Crystal really focused on 
> Ruby developers.

I do not think Nim focuses on Python developers at all. It shares some 
syntactic constructs with Python, but it is very different. Crystal, on the 
other hand, seems indeed to be very focused on Ruby devs.


Re: Execution speed Nim vs. Python

2016-08-11 Thread flyx
cblake: C11 made VLAs an optional feature though. I consider C VLAs a very poor 
solution; as you say, it's mostly syntactic sugar for alloca.

And yes, something between array and seq would be nice. But currently, Nim's 
type system does not allow a type with a runtime-calculated length parameter. 
Allowing it would be a hack similar to C VLAs.


Re: Execution speed Nim vs. Python

2016-08-10 Thread flyx
Stefan_Salewski:

> May it be possible to have one single Seq in each proc on the stack? Of 
> course it has to be the last element, and can only work when that proc do not 
> call other procs.

That may be possible, but far too complicated with far too few impact on 
performance. The compiler would need to properly place the seq, statically 
analyze that no other procs are called, and add special transformation code 
every time you copy this seq. If you have, somewhere in your proc, some code 
`a.b`, where `b` is some field in `a``s type, and you transform ``b` into a 
getter proc at some point in the future, you code suddenly wouldn't be able to 
compile anymore. And this is just one example why it is a really bad idea.

Ada is the one language I know which went a long way for arrays of dynamic 
length which can still be stored on the stack. The only restriction is that an 
array cannot change size after initialization. Therefore, it does not cover all 
use cases and it still needs dynamic container types in its standard library. 
Also, handling those arrays is a bit more difficult than in other programming 
languages. Everything comes at a price.


Re: Execution speed Nim vs. Python

2016-08-10 Thread flyx
> I do not understand the use of the openarray parameter in relation to 
> performance.

`openarray` has nothing to do with performance. It is just a feature to allow 
implementing procs that take both an `array` and a `seq` as parameter.

The actual performance gain stems from using arrays instead of seqs. Because an 
array's length is known at compile time, it can be allocated on the stack. Seqs 
always need to be allocated on the heap. Therefore, it is always advisable to 
use arrays when possible. Other performance optimizations are explained in the 
previous posts.

> If the length of the output array of a proc is not known in advance, are 
> there general rules to accomplish a good performance?

If you can calculate the target length of the array efficiently before actually 
filling it, initialize the result seq with as many elements as needed (as shown 
in the other posts) or use `newSeqOfCap` if you're on devel or once this has 
made it into a release.


Re: spawninig of more than 8 threads problem

2016-08-09 Thread flyx
Well, I'm done with ideas. If you want to investigate further, I guess gdb or 
lldb would be able to help you see what's happening.


Re: spawninig of more than 8 threads problem

2016-08-09 Thread flyx
On second thought, the scheduler may be intelligent enough not to start more 
than one thread if it knows that they all wait for the same resource. But I 
wouldn't assume it.


Re: spawninig of more than 8 threads problem

2016-08-09 Thread flyx
Well it works for me with 32 characters in the string (Linux, 4 CPUs). So it 
seems to depend a bit on the OS - and therefore, the scheduler.

> I think this shouldn't be the case.

I'll try to explain what might happen. I do not know all internals involved, so 
it may or may not be accurate.

Suppose all the threads have been started and we are at some point _x_ where 
one thread just finished writing its character. That thread releases the lock, 
and the scheduler sees „ah, the lock has been released, I have a bunch of 
threads waiting for that, let's wake the next in line. And because I have 
multiple CPUs, let's directly start multiple threads.“

The next thread in line - lets call it `T1` \- executes and acquires the lock. 
Unfortunately, it is not the thread that can write the next character. So it 
releases the lock and goes to sleep for 1ms. Meanwhile, another thread (`T2`) 
has been started and tries to acquire the lock again, but `T1` is still holding 
the lock. So `T2` tells the scheduler it is still blocked by the lock and goes 
to sleep again. The scheduler moves it to the back of the queue of blocked 
threads. Now, unfortunately, `T2` is actually the thread that can write the 
next character. But the scheduler will now execute all the other threads first. 
Then, if you're lucky, `T2` will finally be executed because all other threads 
currently sleep.

This, however, will only happen if the scheduler can make all the necessary 
context switches between threads, all the executions and sleeps etc, in less 
than 1ms (the time the other threads sleep). Depending on your system, that may 
or may not be enough time (I do not have the metrics on context switches at 
hand, so I can only guess). If a round-trip through all the threads takes more 
than 1ms, it can happen that `T2` is blocked again by another thread when it is 
its turn to execute. And the same circle happens again. So it cannot be 
guaranteed that `T2` will ever be executed while the lock is acquirable by it.

You may try to increase sleep time. But all in all, this code is outright 
horrible because of those interdependencies, and you should never do something 
like that in production code.


Re: spawninig of more than 8 threads problem

2016-08-09 Thread flyx
The problem is that threads _go to sleep while still holding a lock_.

Well, the real problem is that afaik there is no guarantee that this code will 
ever finish, because the scheduler is not required to ever wake the right 
thread when a bunch of other threads are still waiting. But anyway, Moving the 
`sleep` call behind the lock seems to work fine in practice:


import unicode, threadpool, locks, os

proc lenU*(s: string): int =
  result = s.runeLen

proc charAtPosU*(s: string, pos: int): string =
  assert(pos >= 0 and pos < s.runeLen)
  result = s.runeAtPos(pos).toUTF8()

proc multithreadedPrint(sMsg: string, nCount: int) =
  var
nLen = sMsg.lenU
nCallsTotal = 0
nCallsCur = 0
lk: Lock
res = 0
  
  proc worker(c: string, value: int) {.gcsafe.}=
while true:
  var found = true
  acquire(lk)
  try:
if nCallsCur == nCallsTotal:
  return
if res == value:
  inc res
  res = res mod nLen
  inc nCallsCur
  stdout.write c
else:
  found = false
  finally:
release(lk)
  if not found: sleep(1)
  
  if nLen > 0:
if nLen > MaxDistinguishedThread:
  echo "Your string is too long. Maximum allowed is ", 
MaxDistinguishedThread, "!"
  return
setMinPoolSize(nLen)
setMaxPoolSize(nLen)
initLock(lk)
try:
  nCallsTotal = nLen * nCount
  echo("Total threads: ", nLen)
  echo("Total calls: ", nCallsTotal)
  for i in 0..

Re: TaintedString.parseInt problem

2016-08-07 Thread flyx
@luntik2012: From documentation of `execProcess`:

> WARNING: this function uses poEvalCommand by default for backward 
> compatibility.

This means that it executes the command within a shell, which is probably 
responsible for the trailing newline.

@Stefan_Salewski: Well, it's easy enough to implement:


import strutils, future

proc hexDump(s: string) =
  echo lc[toHex(int8(c)) | (c <- s), string].join(" ")

hexDump("123\n")


yields:


31 32 33 0A



Re: TaintedString.parseInt problem

2016-08-07 Thread flyx
The problem is that the result of `execProcess` contains trailing whitespace (a 
newline in this case). Try:


return execProcess(command & "" & filepath & ) / 
1000""").strip.parseInt



Re: Inline ASM

2016-08-05 Thread flyx
Look 
[here](http://forum.nim-lang.org///nim-lang.org/docs/manual.html#statements-and-expressions-assembler-statement).


Re: Nim how to write plug-ins to achieve dynamic loading?

2016-08-05 Thread flyx
Compile your plugins with `--app:lib`, then use the `dynlib` module in the main 
program to load them at runtime.


Re: How do I pass an operator as proc parameter?

2016-08-03 Thread flyx
Usually, you would define `action` as `proc(l,r: T): T`. But this does not work 
for `xor` because of this paragraph in the manual ([see 
also](https://github.com/nim-lang/Nim/issues/2172)):

> Assigning/passing a procedure to a procedural variable is only allowed if one 
> of the following conditions hold:
> 
> * The procedure that is accessed resides in the current module.
> 
> * The procedure is marked with the procvar pragma (see procvar pragma).
> 
> * The procedure has a calling convention that differs from nimcall.
> 
> * The procedure is anonymous.

`xor` is not in the current module, not marked with `{.procvar.}`, has the 
calling convention `nimcall` and is not anonymous, so it may not be passed to a 
procedural variable.

You can, however, use a template:


template bitWise*[T](buff: openArray[T], action: untyped, mask: 
openArray[T]): seq[T] =
  var result = newSeq[T]()
  for i in 0..

Re: Dynamic Object Type Fields

2016-07-30 Thread flyx
This is not possible by design.


type
  test* = object


Here, you declare an object that has no fields.


var t = test()


Here, you instantiate this object. `t` has the type `test`.


var t.name = "kek"


The compiler now looks at `t`'s type and sees that this type has no field 
`name`, and thus quits with an error at compile time. If you want to allow 
that, that means that every construct `t.someFieldName` would not be allowed to 
fail at compile time (because that field may be added dynamically). So the 
compiler can no longer guarantee that the field you try to access exists. 
That's the difference between static and dynamic typing systems.

The question is: Why do you think you need it?


Re: Opengl vertices

2016-07-28 Thread flyx
The OpenGL wrapper provides a `GLvectorf3` type, why don't you use that? Also, 
you should show more of your code for us to see what you are actually doing.


Re: Convert seq into tuple

2016-07-28 Thread flyx
> I hope I'm wrong and there is an elegant way to define a large tuple.

What do you need a tuple this size for? Your problem is likely that you use the 
wrong tool for the job. The need to write


var myTuple: tuple[a00,a01,a02,a03,a05 ... a98,a99: int]


roots from the nature of the tuple type. If you do not want to do that, you 
likely do not want to use a tuple.


Re: gensym pragma with names of entity passed as template parameter not working as expected

2016-07-27 Thread flyx
You cannot `gensym` the pragma since it is injected as parameter. But you can 
simply enclose the template body in a block:


template foo(txn, body: untyped): untyped =
  block:
let txn = 1
body

foo hello:
  echo hello

foo hello:
  echo hello



Re: Convert seq into tuple

2016-07-27 Thread flyx

proc fillTuple[T: tuple, V](target: var T, input: openarray[V]) =
  var index = 0
  for field in target.fields:
assert input.len > index
field = input[index]
inc(index)

var myTuple: tuple[a,b,c: int]

fillTuple(myTuple, @[1, 2, 3])


Or, if you want the tuple as return value:


proc fillTuple[T: tuple, V](input: openarray[V]): T =
  var index = 0
  for field in result.fields:
assert input.len > index
field = input[index]
inc(index)

var myTuple = fillTuple[tuple[a,b,c:int], int](@[1, 2, 3])



Re: macro changing type of const literals not working

2016-07-19 Thread flyx
Works for me on devel. However, the bit with the `include` does not.


Re: [macro] Adding echo to a function

2016-07-06 Thread flyx

import macros

macro addEcho(s: untyped): stmt =
  s.body.add(newCall("echo", newStrLitNode("OK")))
  result = s

proc f1() {.addEcho.} =
  let i = 1+2
  echo i


You have to use untyped because with stmt, Nim seems to create a symbol f1 
beforehand and then gets confused about it because you return a proc f1 again 
with the same signature. This should probably be reported as bug, because it 
should at least generate a sensible error message.