Run process in parallel of the parent program
I tried for something like this: import system, os, osproc, threadpool import locks var thr1: Thread[string] thr2: Thread[string] L: Lock proc threadExec(p: string) {.thread.} = discard execProcess(p) proc threadQuit {.thread.} = os.sleep(1000) quit(1) initLock(L) createThread(thr1, threadExec, (paramStr(1))) createThread(thr2, threadQuit) joinThreads(thr1,thr2) quit(1) Run To immediately stop parent process after child process execution but, without responce from childside. So is' there an example of how to implement it correctly, not like a thread, just mb it's already implemented option.
What's the future of "implicitDeref"?
When doing manual memory management in Nim, I often find myself having to define two versions of a proc - one that takes a `var` parameter and one that takes a `ptr` parameter. Otherwise I will run into issues like this: var m: ptr Monster var b: Bullet proc chooseAnim(m: var Monster) = # some logic to set the current animation # ... proc update(b: ptr Bullet) = # move the bullet and check for collisions # ... m.chooseAnim() # uh oh! m[].chooseAnim() # better. b.update() # uh oh! (addr b).update() # better. Run I was happy to discover that [{.experimental: "implicitDeref".}](https://nim-lang.org/docs/manual.html#types-reference-and-pointer-types) is a thing, which pretty much fixes all my problems! If I define the `var` version of the procedure, I don't need to define the `ptr` version anymore. But I suppose I can't start doing this in library code yet, because then I'd be forcing other people to use this experimental pragma in their code, or to have to worry about addressing/dereferencing their stuff to make the library functions happy. So I was wondering, what's the future of this feature? Do we know yet if it's here to stay? Does it have any caveats that I should know about? Thanks :)
Re: Problem sending binary file by socket never ending.
I found the problem. The server must not use the buffering mode otherwise it waits that buffer is full. var server = newAsyncSocket(buffered=false) Run Thanks
Nimterop release update
[Nimterop](https://github.com/nimterop/nimterop) v0.6.0 has just been released and adds the ability to download pre-compiled binaries from [Conan.io](https://forum.nim-lang.org/conan.io/center/) and [BinaryBuilder.org](https://binarybuilder.org/) using [getHeader()](https://nimterop.github.io/nimterop/build/getheader.html#getHeader.m%2Cstatic%5Bstring%5D%2Cstatic%5Bstring%5D%2Cstatic%5Bstring%5D%2Cstatic%5Bstring%5D%2Cstatic%5Bstring%5D%2Cstatic%5Bstring%5D%2Cstatic%5Bstring%5D%2Cstatic%5Bstring%5D%2Cstatic%5Bstring%5D%2Cstatic%5Bstring%5D%2Cstatic%5Bstring%5D%2Cstatic%5BopenArray%5BBuildType%5D%5D) and copying shared libraries to a specified **libdir**. In addition, the legacy backend has been removed and a few other minor features that make wrapping easier. Find the full changelog [here](https://github.com/nimterop/nimterop/blob/master/CHANGES.md#version-060).
Re: Change Nim colour on GitHub
PR for color change has been merged: [https://github.com/github/linguist/pull/4900](https://github.com/github/linguist/pull/4900)! It will go live on next release. Last release was 10 days ago, so we will probably wait at least a month for that.
Re: Problem sending binary file by socket never ending.
I can do that but my binary files can be very big.
Re: How to use inheritance?
And finally this may look more like what you may desire: import gintro/[gtk, gobject, gio] type Header = ref object of Headerbar text: string MainWindow = ref object of gtk.ApplicationWindow header: Header pb: ProgressBar proc appActivate(app: Application) = let window = newApplicationWindow(MainWindow, app) window.borderWidth = 10 window.header = newHeaderbar(Header) window.header.setShowCloseButton window.header.setTitle("MainWindow") window.header.setSubTitle("Subtitle") window.pb = newProgressBar() window.add(window.pb) window.pb.setFraction(0.25) window.defaultSize = (400, 400) window.setTitlebar(window.header) window.showAll() proc main = let app = newApplication("org.gtk.example") connect(app, "activate", appActivate) discard run(app) main() Run Please note that you should add destructors for the subclassed widgets if you intent to compile with ARC, see the gintro README.
Re: Choosing Nim
The CERN ROOT effort is indeed a wrapper: [https://github.com/watson-ij/nim-root](https://github.com/watson-ij/nim-root), but it could provide an interface to ROOT which could be useful? Goodness your code looks quite extensive! I am sure your community would be interested in reusing some of your code. Just a thought, have you considered giving a talk at CHEP? To me, it looks like it would be worthy of a talk at CHEP ([https://www.jlab.org/conference/CHEP2021)](https://www.jlab.org/conference/CHEP2021\)). I am not in the committee (certainly not an academic), but I would think there's a place for it. Incidentally, I personally hope they make the conf virtual as I'm not sure things will be fine in May/21 (I hope so, but I am not sure). I've heard of neutrinos as my wife works on T2K and Hyper-K.
Re: How to use inheritance?
And to give you a starting point, the basic shape of your above program would look like this: import gintro/[gtk, gobject, gio] type Header = ref object of Headerbar text: string MainWindow = ref object of gtk.ApplicationWindow header: Header pb: ProgressBar proc newHeader(): Header = result = newHeaderbar(Header) result.text = "Initial Title" result.setTitle("Title") discard result.showCloseButton proc newMainWindow(gtkApplication: Application): MainWindow = result = newApplicationWindow(MainWindow, gtkApplication) result.header = newHeader() result.pb = newProgressBar() result.add(result.pb) result.pb.setFraction(0.25) result.setSizeRequest(400, 400) result.setTitlebar(result.header) result.showAll() proc appActivate(app: Application) = let window = newMainWindow(app) proc main = let app = newApplication("org.gtk.example") connect(app, "activate", appActivate) discard run(app) main() Run For me it compiles and runs, but I think it does not look like you intend. I can not really test it as my current gintro is modified for my GTK4 experiments. Hopy you can tune it yourself.
Re: How to use inheritance?
OK, when it is gintro related then your initial post is really not that smart. Inheritance for C libs in different from inheritance in Nim . C is not an OOP language. I would strongly suggest YOU not using gintro! I have recently listed most of the Nim GUI packages here, located directly above Chapter 1 heading: [http://ssalewski.de/gtkprogramming.html](http://ssalewski.de/gtkprogramming.html) All that packages are great. If I miss other packages please let me know. If you will still continue with gintro, I gave an example of subclassing here: [http://ssalewski.de/gintroreadme.html#_extending_or_sub_classing_widgets](http://ssalewski.de/gintroreadme.html#_extending_or_sub_classing_widgets) It is not well tested, and it is different from native Nim and different from GObject C subclassing. As we use proxy objects in gintro. Nim inheritance is explained here: [http://ssalewski.de/nimprogramming.html#_object_orientated_programming_and_inheritance](http://ssalewski.de/nimprogramming.html#_object_orientated_programming_and_inheritance)
Re: How to use inheritance?
I don't think it's gintro specific. I have never used inheritance in Nim before so I just need to get started with the basics. import gintro/[gtk, gobject, gio] type Header = ref object of RootObj base: HeaderBar text: string # Header = ref object of HeaderBar # text: string MainWindow = ref object of RootObj base: ApplicationWindow header: Header pb: ProgressBar proc newHeader(): Header = new(result) result.base = newHeaderBar() result.text = "Initial Title" result.base.setTitle(result.text) result.base.setShowCloseButton(true) # proc newHeader(): Header = # new(result) # result.text = "Initial Title" # result.setTitle(result.text) # result.setShowCloseButton(true) proc newMainWindow(gtkApplication: Application): MainWindow = new(result) result.base = newApplicationWindow(gtkApplication) result.header = newHeader() result.pb = newProgressBar() result.base.add(result.pb) result.pb.setFraction(0.25) result.base.setSizeRequest(400, 400) result.base.setTitlebar(result.header.base) # result.base.setTitlebar(result.header) result.base.showAll() proc appActivate(app: Application) = let window = newMainWindow(app) proc main = let app = newApplication("org.gtk.example") connect(app, "activate", appActivate) discard run(app) main() Run If I use composition as I above it works but if I toggle the comments, I get the following warning: (helloprogress:19510): Gtk-CRITICAL : 01:02:02.771: gtk_header_bar_set_title: assertion 'GTK_IS_HEADER_BAR (bar)' failed (helloprogress:19510): Gtk-CRITICAL : 01:02:02.771: gtk_header_bar_set_show_close_button: assertion 'GTK_IS_HEADER_BAR (bar)' failed So Gtk resorts back to regular titlebars.
Re: Problem sending binary file by socket never ending.
Try client.recv(fileSize)
Re: How to use inheritance?
I hope it is not related to gintro?
How to use inheritance?
Hi, I want to create a derived type and call methods of the based type. How does one achieve this? I was trying to just call the method on the result type as follows: type Header = ref object of HeaderBar text: string proc newHeader(): Header = new(result) result.text = "Initial Title" result.setTitle(result.text) result.setShowCloseButton(true) # If I was using composition (too much boilerplate) # type # Header = ref object of RootObj # base: HeaderBar # text: string # proc newHeader(): Header = # new(result) # result.base = newHeaderBar() # result.text = "Initial Title" # result.base.setTitle(result.text) # result.base.setShowCloseButton(true) Run However GTK was warning me that my `Header` isn't a `HeaderBar`. Is there a way to get the parent type from a derived type?
Re: Nuglifier - Nim source code uglifier
Since I suspect it'll come up: You can compare it to Java public class HelloWorld{ public static void main(String []args){ \u0053\u0079\u0073\u0074\u0065\u006D\u002E\u006F\u0075\u0074\u002E\u0070\u0072\u0069\u006E\u0074\u006C\u006E("Hello World"); } } Run
Re: Nuglifier - Nim source code uglifier
Translation to C is in itself a pretty effective uglier.
Re: Choosing Nim
> The experiment I worked on was BaBar at SLAC. Oh, that's nice and also a kind of a funny coincidence. That means you were involved with an experiment studying weak CP violation whereas we're now trying to study strong CP violation, heh. > Although the simulation and reconstruction and analysis code was written in > C++ book-keeping was better done in a scripting language. It was easier to do > this in Python. I _think, but you would know better, Python has moved to the > analysis area too. So, more researchers are using Python there. Yes, a lot of people use Python all over the place in physics now. Most of my ATLAS colleagues write their ROOT scripts using pyroot / rootpy instead of ROOT's C++ abomination. Which is always kind of funny when you see them talking about "running python" but encountering segmentation faults... :) > For analysis, I think Nim could have an advantage as it's faster. I think the > time to develop the code is about the same, but Nim would reduce the > execution time. It would also help to reduce the debugging time as a chunk of > time is spent keeping track of which variables are which type. Oh yes, for sure! Unfortunately I feel most physicists don't realize that dynamic typing is a burden. > I think I recall that someone wrote an interface to ROOT for Nim, so you can > read and manipulate your data in Nim. Yes? I haven't seen that. Sounds to me like creating that wrapper would be kind of a pain, given how ROOT is 1. C++ and 2. essentially provides its own standard library. > For your analysis are you using Nim? I think that would be a great thing. I > know nothing about Axions, or searches for Axions. I should look it up to > find out more. Yep, I'm writing my whole analysis in Nim. Since the axion community is still pretty tiny (although it has been growing and should grow even more now after the last European Strategy for Particle Physics update, which really endorses axion searches) I'm not really forced to use some existing analysis framework. There was some code written by my predecessor, but that was all ROOT and MarlinTPC. Threw it all away and started from scratch. Code is here: [https://github.com/Vindaar/TimepixAnalysis](https://github.com/Vindaar/TimepixAnalysis) It's one big mono repository for my whole thesis essentially though. The most interesting code is the Analysis directory. In general axion searches all deal with the same big problem: given that axions haven't been detected yet, it means their detection via some interaction is hard (-> coupling constants are tiny). What does that imply? Of course that no matter what kind of experiment one builds, all sorts of background will massively dominate everything one measures. So they are all very low rate experiments, which need the best possible background suppressions (both hardware and software wise) as possible. In that sense it's a little similar to neutrino experiments, except even worse. Also neutrino experiments of course have the benefit nowawadays of simply having a lot more manpower and money to build in better locations (e.g. waaayy below ground to shield from cosmics) than we do. My experiment - CAST - is simply sitting in a random hall at surface level at CERN. The only shielding from muons I have is ~20 cm of lead. So there's still like ~1 muon every couple of seconds in my detector. What we want to measure are X-rays which are the result of axions entering our magnet (LHC prototype dipole magnet, 9 m long, 9T magnetic field) and interacting with the virtual photons of the magnetic field. These would just be the result of X-rays interacting in the Sun and randomly converting to axions and then leave the Sun unhindered. Have a great weekend!
Re: Problem sending binary file by socket never ending.
Thank you for the idea to send the file size :) I modified the code to receive the file size et I add a counter of byte. But the server never get last data. I think that the server waits a buffer of size **4000**. The Client: import net, streams, os let client: Socket = newSocket() client.connect("127.0.0.1", Port()) stdout.writeLine("Client: connected to server on address 127.0.0.1:") while true: stdout.write("> ") let filename: string = stdin.readLine() var data = newString(4000) let file = open(filename, fmRead) let size = getFileSize(file) echo "File size is :" & $size echo "Send file size" client.send($size & "\c\L") echo "Pull ..." sleep(100) while true: let len = file.readBuffer(addr(data[0]), 4000) setLen(data, len) if len == 0: break else: echo "Send data size : " & $len client.send(data) echo "End of file" file.close() client.close() Run The Server import asyncnet, asyncdispatch, parseutils proc processClient*(client: AsyncSocket) {.async.} = var fileSize: int counter: int while not client.isClosed: echo "Wait file" var file = open( "receive.7z", fmWrite ) let sizeFileString = await client.recvLine() discard sizeFileString.parseInt(fileSize) echo "File Size is " & $fileSize counter = 0 var dataFut = client.recv(4000) while true: yield dataFut echo "Counter : " & $counter if counter >= fileSize: break else: if dataFut.finished: let data = dataFut.read if data != "": counter += data.len file.write(data) dataFut = client.recv(4000) else: echo "No data" break else: echo "Exit" break echo "End of file" file.close client.close() proc serve() {.async.} = var server = newAsyncSocket() server.setSockOpt(OptReuseAddr, true) server.bindAddr(Port()) server.listen() echo "Server run !" while true: let client = await server.accept() echo "Connect client" asyncCheck processClient(client) asyncCheck serve() runForever() Run Have you any idea ?
Re: Choosing Nim
Thanks! I'm a bit old fashioned (I still use mutt for my mail client). I switched from emacs to vim and am now trying neovim. In the past, I tried Eclipse, netbeans, but I must have been using them incorrectly as I found the memory consumption to be very high. I have tried Atom a few times but again noticed significant memory consumption (I am clearly doing something wrong). I've not tried Visual Studio. It is great the Microsoft is embracing a more open to software.
Re: Choosing Nim
Oooh! Lovely! Your gitlab link is fascinating. I am not sure I have the wherewithal to contribute, but it's very interesting! Thank you.
Re: Can't install the bin tarball of nim 1.2.2.
We have just released Nim 1.2.4 — it is a hotfix release which deals with the `nim-gdb` problem mentioned in this thread.
Re: Nim version 1.2.2 is out!
We have just released Nim 1.2.4 — it is a hotfix release which deals with the `nim-gdb` problem mentioned in [this thread](https://forum.nim-lang.org/t/6460). The complete changelog is available [here](https://github.com/nim-lang/Nim/compare/v1.2.2...v1.2.4).
Re: Nuglifier - Nim source code uglifier
I... translated the strutils module. Of course there were a lot of problems with indentation, but I fixed them all in ~10 minutes! :) Also I removed a couple of tests (the ones with test indent), but it WORKS! [https://gist.github.com/Yardanico/9a2677bd8d7c5e0e869cbe451dd175cc](https://gist.github.com/Yardanico/9a2677bd8d7c5e0e869cbe451dd175cc)
Re: Nuglifier - Nim source code uglifier
> [https://gist.github.com/Yardanico/9a2677bd8d7c5e0e869cbe451dd175cc](https://gist.github.com/Yardanico/9a2677bd8d7c5e0e869cbe451dd175cc) > gonna use that to scare people on hackernews
Nuglifier - Nim source code uglifier
Hello! So a few days ago we were having fun in #nim-offtopic (#offtopic in Discord) and made this - [https://play.nim-lang.org/#ix=2qcg](https://play.nim-lang.org/#ix=2qcg). Then I thought "that's so cool!" and decided to try to make something even **better**. I present to you - **Nuglifier - the (not yet) ultimate Nim source code uglifier /obfuscator!** An example for what it can do (part of the full source file) Before: import math, strutils, parseutils, tables, strformat type MathFunction* = proc(args: seq[float]): float ## \ ## Type of the procedure definition for custom math functions MathCustomFun = object # Number of arguments this function is allowed to be called with argCount: int # The function itself fun: MathFunction MathExpression = object eval: Evaluator input: string len: int ch: char pos: int Evaluator* = ref object ## Main instance of the math evaluator hasFuncs: bool hasVars: bool funcs: TableRef[string, MathCustomFun] vars: TableRef[string, float] proc atEnd(expr: var MathExpression): bool = expr.pos >= expr.len Run After (I can't paste zero-width space on Nim forum so it doesn't look as indented and won't compile if you copy-paste) #? replace(""," ") | replace("\t"," ") iMP_orT math, strutils, parseutils, tables, strformat # import line modified since imports are broken with case ty_PE Mat_HFu_Nc_TI_On* = pR_OC(aR_GS: sEq[fL_OAT]): fL_OaT ## \ Mat_hCusT_OMF_UN= oB_JE_CT ar_gC_ouNt:inT fUN:Mat_hF_UN_ctI_ON MATh_Ex_pR_eSS_ION=ob_JE_CT evAL:EV_aLU_AToR iN_PUT:sT_RI_Ng len: int cH:cH_AR pOS: int EV_aLU_At_oR*=rEFoBJEct ha_SF_UNCS:booL ha_SV_ARS:bO_Ol fUnCS: TAb_leR_eF[sT_rI_NG,MA_tH_Cu_St_OM_FUN] vA_rs: TABL_eR_Ef[sTR_inG, flOAt] procaTE_ND(eX_PR:vARMAt_HEXP_reSSi_oN):bO_ol= eX_PR.pOS >= ex_Pr.lEn pROCin_CPOS(eXpR:varMaTh_EXPR_Es_SI_ON,ad_dP_oS=1):cH_aR{.dI_SC_Ar_da_bLE.}= exPR.pOs+=aDD_POs eX_PR.cH=ifex_PR.aT_ENd():'\0'eL_SE:eXpr.inP_Ut[ex_pR.poS] Run Full examples of generated code are at Case insensitivity - [https://raw.githubusercontent.com/Yardanico/nuglifier/master/example_output/example_case.nim](https://raw.githubusercontent.com/Yardanico/nuglifier/master/example_output/example_case.nim) Emojis - [https://raw.githubusercontent.com/Yardanico/nuglifier/master/example_output/example_emoji.nim](https://raw.githubusercontent.com/Yardanico/nuglifier/master/example_output/example_emoji.nim) # How does it work? Right not it's pretty "simple" \- first of all, I used Nim's own lexer (took it out of the compiler) to replace different symbols with new ones (e.g. change their casing or replace them with emojis). If it replaces with emojis - right now I do it the "dumb" way and just _haha SCFs go brrr_ \- [https://nim-lang.org/docs/filters.html](https://nim-lang.org/docs/filters.html) (Maybe I should look into using Nim compiler to parse AST to actually replace symbols only without cheating with SCFs.) After that I run my own small loop for indentation which changes it to one of 1 random characters (tab, zero-width space or normal space) for random depth. Even if it's pretty simple right now, the results are already _very good_ Source code at [https://github.com/Yardanico/nuglifier](https://github.com/Yardanico/nuglifier) I'm open for feedback on this abomination, feel free to comment :)
Re: Procedure overloading with explicit parameters
> magine swapping out Nim's object variants for Rust's enums. I think that > would be an improvement. > > Araq has explained on several occasions why he designed Nim's object variants > the way he did. Well you're both right. :-) The current design has its advantages but Rust's seems nicer. However, Rust's only works with more borrow checking, IMO. I couldn't copy Rust's design for Nim's case objects because back then Rust didn't exist. I knew ML's but ML's works because of its immutability.
Re: Procedure overloading with explicit parameters
> magine swapping out Nim's object variants for Rust's enums. I think that > would be an improvement. Araq has explained on several occasions why he designed Nim's object variants the way he did. A quick google produced this comment (not from Araq): [https://news.ycombinator.com/item?id=9051122](https://news.ycombinator.com/item?id=9051122)
Re: Procedure overloading with explicit parameters
> Since Nim is not a functional, but imperative language, you would use runtime > flow control in this case: proc fac(n: int): int = if n == 0: 1 else: n * fac(n - 1) Run There isn't anything non-functional about that.
Re: Procedure overloading with explicit parameters
> the different functions with the same name get merged together What different functions? There's only one function given in your example, the one defined by the type signature: factorial :: (Integral a) => a -> a Run It's quite wrong to interpret factorial 0 = 1 factorial n = n * factorial (n - 1) Run as function definitions--they are _patterns_ , very similar to (a, b) = iReturnATuple() Run in Nim, which is a limited form of pattern matching. > As others have already said, it's runtime polymorphism Anyone who says that is quite wrong. It's no more "runtime polymorphism" than a case statement is.
Re: Procedure overloading with explicit parameters
> Procedure overloading is the ability to define different implementations of > procedures with the same name. Each of these procedures shares the same name > but accept different parameters. Depending on the arguments passed to the > procedure, the appropriate implementation is picked by the compiler. > > In my interpretation fac(0) satisfies this definition How, odd, because it surely doesn't; 0 is not a parameter. Parameters are typed symbols that abstractly represent the values passed to a procedure; they are not values and are in a different conceptual space from values. fac(0) is an invocation of a procedure, not a definition of one. The quoted text could be clearer by saying "accept different numbers of parameters or parameters of different types". This really isn't a matter of functional vs. imperative languages, it's a matter of basic language syntax. Functional languages need not offer Haskell-style matching syntax, and imperative languages could. Note that, in Haskell, you have to provide a type signature in addition to the pattern matching; the type signature is comparable to procedure signatures in Nim and other languages. Note that Haskell's factorial :: (Integral a) => a -> a factorial 0 = 1 factorial n = n * factorial (n - 1) Run looks nothing like your proc fac(0): int = 1 proc fac(n: int): int = n*fac(n-1) Run The Haskell has a type signature and then two lines that match the value of the argument. Your first line is a mishmash of the two concepts and fails to identify the type of 0. No language works like that because it would be terrible language design.
Re: New garbage collector --gc:orc is a joy to use.
> Is that the plan? Almost. We need to run the cycle collector before a send already to ensure the thread local "cycle candidates" list is empty (note that it is always empty after a cycle collection), otherwise it would interfere with multi-threading. Alternatively we can make the list global and protected via a lock (or implement it as lockfree queue...). There are many other options, we can also restrict the sending to `.acyclic` types. Or we request that "orphaned objects" that will be misdetected as false external roots to be cleaned up manually. That is a good idea anyhow, ensuring the programmer he still aware of the typology: proc process(x: Node) = use(x.left) # likely invalid: spawn process(x.right) # better: extract it spawn process(move x.right) Run