IRC channel logs

2015-12-23.log

back to list of logs

<nalaginrut>ACTION saw `monads' in Guix, hmm...
<dsmith-work>Morning Greetings, Guilers
<tj__>hey, how can i evaluate a quoted expression? for example, i have '(* 2 4), how can i get the result out?
<tj__>dsmith-work: greets, it's evening in east-european time though... : D
<artyom-poptsov>tj__: I suppose 'primitive-eval' might be the procedure that you're looking for.
<tj__>artyom-poptsov: so, (primitive-eval '(* 3 4)) will give me 12...
<tj__>yup, it's weird though, i imagined it would have a one-character function or something, smth quick and easy to remember... is it not a common procedure?
<mark_weaver>tj__: I don't think I've ever used 'eval' in over 15 years of programming scheme
<tj__>mark_weaver: hmm... i use it all the time, i heard it's dangerous though : )) 'n i have no formal training
<rjmacready>mark_weaver: come on.... there was *that* time ... ;)
<mark_weaver>tj__: what do you use it for?
<tj__>mark_weaver: piping scripts together, evaluating form stdin
<mark_weaver>I'm not sure what "piping scripts together" means.
<mark_weaver>as for evaluating from stdin: why not use the REPL? I'm not sure why that would be a common thing to want to do.
<rjmacready>isnt there a way to load stdin as if it were a file?
<unknown_lamer>`read;
<rjmacready>like (load stdin) or something like that
<unknown_lamer>`read' rather
<tj__>in unix/linux, you can do: $ ./a_script | ./another_script and you redirect the stdout of one to the stdin of the other
<mark_weaver>tj__: okay, but I don't see how 'eval' helps with that.
<tj__>mark_weaver: you get the stdin in the form of a string, i use string-eval to get the contents
<unknown_lamer>tj__: if you just need the sexp, you can use read
<tj__>unknown_lamer: ah, let me try it out
<unknown_lamer>it's not great security practice to eval random input -- if I were sending commands between two scripts I'd make a simple command language and `read' it in and then use (match ...) or similar to parse it
<mark_weaver>I'm not sure I would trust our 'read' to hostile input either
<tj__>unknown_lamer: yeah... it's a bit slower though, i'm doing that in haskell usually, making interfaces between programs, haskell has the parsec library and it's easy to write really complex parsers in it.
<tj__>mark_weaver: chill, it's just for hacking stuff together, quick'n dirty
<tj__>mark_weaver: and it's lisp, it's rebelious by nature
<mark_weaver>sure, do as you wish, of course.
<unknown_lamer>mark_weaver: hrm, why not though? I've never thought read was inherently insecure or anything (parsing fails... you just get an error)
<tj__>rjmacready: sorry for the delay, current-input-port defaults to stdin, it's exactly what you're sayn
<rjmacready>tj__: ah nvm, i was just shooting in the dark :)
<unknown_lamer>mark_weaver: doesn't seem like read expands quasiquote, the only thing I'd be leery of (but also I've been doing more SML than Lisp lately, maybe I'm missing something)
<mark_weaver>unknown_lamer: well, for one thing, Guile's 'read' is globally extensible, and e.g. there's the #. extension that evaluates arbitrary expressions at read time. it's disabled by default, but can be enabled by simply setting the 'read-eval?' fluid.
<mark_weaver>but even with no user extensions, guile has a lot of extensions to read syntax and the code is quite complex and hasn't been audited for safety in the case of deliberately hostile input.
<mark_weaver>and of course, even if it was perfectly written, by design there's no limit in the amount of memory allocated by 'read'.
<mark_weaver>probably there are some potential integer overflows lurking, at least.
<unknown_lamer>ah
<unknown_lamer>pesky potential unbounded memory use
<rjmacready>the (min sky memory-limit) is the limit :v
<rjmacready>i'll see myself out :(
<tj__>rjmacready: : ))
<tj__>rjmacready: i din't know there was a built in function for minimum, i was allways defining one
<rjmacready>eh i dunno if it's that one either :)
<tj__>it is tho... : ))
<rjmacready>its a joke with pseudocode lets say
<rjmacready>ah nice :)
<mark_weaver>'min' and 'max' are standard scheme procedures since the early days.
<tj__>mark_weaver: good to know... it was getting tedious, use-modules'ing srfi-1 all the time for the fold function
<tj__>mark_weaver: do you think min is implemented in C or is it something like this?
<tj__>(define min
<tj__> (lambda xs
<tj__> (reduce (lambda (a b)
<tj__> (if (< a b)
<tj__> a
<tj__> b))
<tj__> #f
<tj__> xs)))
<mark_weaver>tj__: it's implemented in C
<mark_weaver>and it handles things like NaNs better than what you wrote above
<mark_weaver>and propagates exactness information
<tj__>yeah, i did (min '()) and it gives an error, i don't know how to immitate that
<mark_weaver>min doesn't take a list
<tj__>mark_weaver: a, fuck... : ))
<mark_weaver>well, the standard 'min' doesn't.
<mark_weaver>but it takes an arbitrary number of arguments.
<mark_weaver>so you can (apply min <list>)
<tj__>yeah, that's what i just learned (define func (lambda xs (mess-with xs)))
<tj__>mark_weaver: (apply min <list>) ? that's dope, didn't know that
<mark_weaver>I guess I should mention that if the list if really huge, you could overflow the stack that way. in guile-2.2 it won't matter because the scheme stacks are transparently extensible there.
<mark_weaver>but if you need to handle enormous lists, better use 'reduce' or 'fold'
<nalaginrut>debug-mode works fine with modules-monitoring feature~
<nalaginrut>I'll release 0.1.1 soon ;-)
<nalaginrut>when you enabled debug-mode, the app modules will be reloaded on the fly without restarting server, but it's very slow (>500ms per request), so it's just for debug
<tj__>mark_weaver: yup, i think with map and fold all the time, the next step is using unfold too, i know it's a thing in haskell
<dsmith-work>tj__: http://www.total-knowledge.com/~ilya/mips/ugt.html
<amz3>nalaginrut: nice!
<davexunit>nalaginrut: why not just use a REPL?
<davexunit>reloading entire modules is something that is done in languages that don't have a proper REPL
<davexunit>but we do have one
<nalaginrut>what I want to change is that do not ask users "why not use XXX", I'll ask "what you need", they told me "a inotify based monitor mechanism", then I do it. Or tell users "just Ctrl+C and restart the server" is easier for both side
<amz3>in emacs is even easier than that..
<nalaginrut>not all people use emacs
<davexunit>nalaginrut: people ask for inotify-based file reloading because they don't understand REPLs
<davexunit>because inotify and reloading entire files is the best they have in the languages they are used to
<nalaginrut>maybe, but they don't have to
<davexunit>when I write web servers in Guile, I hack on them *live*
<nalaginrut>that's because you don't use MVC
<davexunit>inotify is a tremendous amount of extra complexity
<davexunit>it has nothing to do with MVC
<nalaginrut>in Artanis, it's related
<nalaginrut>it'll load models and controllers on the fly
<nalaginrut>we can't tell people "why not check modify timestamp? inotify is unnecessary"
<davexunit>that's not at all what I'm saying
<davexunit>you don't need to check file timestamps at all
<davexunit>you just evaluate the expression you want at the REPL
<nalaginrut>let me elaborate it, in Artanis MVC, you can't just use reload-module function to reload things properly
<davexunit>this is the workflow that Guile enables
<nalaginrut>there're more steps to be handled
<davexunit>then you've done something wrong.
<nalaginrut>davexunit: no, that's not what you thought
<nalaginrut>the route cache need to clean then regenerate, and controller rules need to refresh
<nalaginrut>all these things can't be done easily for users in REPL by themselves
<davexunit>then you should make it so it can
<nalaginrut>debug-mode will do these stuff for them, plus a monitoring in a row
<davexunit>if artanis users cannot use the REPL, it greatly limits what they can do.
<nalaginrut>they can, if they want to type more things manually
<davexunit>reloading entire files is a weak approximation for a REPL
<nalaginrut>as I said, it's not like what you thought, if you think you just need to take advantage of the reloading and dependency handling by the REPL, then there're more things then you thought
<nalaginrut>I know reload-module in REPL, but frankly, it's not what the way Artanis reload modules. If you use it, then it can't work
<nalaginrut>and that's the problem (maybe feature) of Guile module system
<nalaginrut>not intended design of Artnais
<nalaginrut>Artanis
<amz3>TIL: reload-module
<nalaginrut>I believe I've tried all the methods we can find in Guile, the current implementation is the only way it works
<nalaginrut>that's the reason why I'm still here in 3:30am...
<amz3>ACTION goes to sleep at 21:00 PM
<amz3>:p
<amz3>except today some extra stuff so 21:30PM x)
<mario-goulart>Not sure how relevant this might be for the discussion, but in awful (a web thing for CHICKEN), one possible hack is define a route that reloads stuff when requested. Example: http://wiki.call-cc.org/eggref/4/awful#reloading-awful-from-emacs . Something similar could be made to bind some paths in debug mode to modules to be reloaded in guile/artanis. It's ugly, but some people find it handy while developing.
<davexunit>you shouldn't have to reload modules at all
<davexunit>you just need to re-evaluate top-level forms
<davexunit>procedures and variables
<mario-goulart>Sometimes it's more practical to reload the whole thing.
<nalaginrut>davexunit: your case is not what it works
<mario-goulart>And it's a matter of taste, of course.
<davexunit>it does work, I do this for literally every application I write
<davexunit>reloading modules via inotify hooks is the sledgehammer approach
<mario-goulart>Of course it works, but it doesn't mean that everybody must follow that particular workflow.
<nalaginrut>mario-goulart: yes, I make sure it reload whole thing to avoid some problems, it's ok, since debug-mode is just for debug
<davexunit>I'm going to stop talking about this now.
<nalaginrut>the handler was registered, it won't trigger the scm to be compile&load by REPL
<nalaginrut>that depends on the framework design, not just thinking
<davexunit>if the framework design doesn't allow for this, it is broken.
<davexunit>end of story.
<davexunit>my patience for this has run out. sorry for being harsh. I'm going to go now.
<nalaginrut>it's easy to say, I can complain that Guile could be better as I thought, so does Hurd. BTW, you can still debug it with REPL if you like.
<nalaginrut>I don't know why people dislike inotify. Artanis provide customized file monitoring for users, it can be edited in artanis.conf. It's necessary for users, REPL can only make sure *.scm to be loaded as module, but it won't cover other files, like json or other config file defined by users.
<nalaginrut>of course, one may say, "why not just use s-expr", well, endless...
<nalaginrut>I rethink the way I go, no, I don't think I'm wrong. With inotify, you just need to modify the code then refresh the page, done. But with REPL, you need to move fingers several time. It's the problem I want to avoid. And Artanis is not for Emacs users only, I know it's easy to play REPL for Emacs users.