IRC channel logs

2014-06-25.log

back to list of logs

<nalaginrut>what's the utility of toplevel-define? I want to checkout if a symbol was defined in toplevel, but this function seems useless, (toplevel-define? '+) ==> #f
<nalaginrut>or (toplevel-define? +) ==> #f
<ijp>I don't even have that function
<ijp>oh right, it's a tree-il thing
<ijp>nalaginrut: we have defined? but *why* do you need this?
<nalaginrut>ijp: I'm transferring AST to tree-il, so it's better to know it
<nalaginrut>if it's toplevel, I have to use toplevel instruction in tree-il
<ijp>transferring what AST?
<nalaginrut>my own frontend
<ijp>toplevel-define? just checks if something is a <toplevel-define> record
<nalaginrut>yes, I realized it now
<nalaginrut>but is there way to check a symbol defined in toplevel?
<ijp>defined?
<nalaginrut>defined? will check the current module
<nalaginrut>in default
<nalaginrut>is there something like toplevel-module ?
<ijp>for what purpose?
<nalaginrut>(defined? 'what-ever (toplevel-module)) is what I need
<ijp>there is a module-defined?
<ijp>but I don't understand why you are checking these dynamically in your tree-il generation
<nalaginrut>some procedures maybe defined in toplevel, and my implementation uses them
<nalaginrut>the Guile primitives in tree-il need (toplevel x) instruct to get
<nalaginrut>or (primitive x)
<ijp>in your generated code, you should know which procedures you have defined in your module (toplevel)
<nalaginrut>yes, I can do it
<nalaginrut>but some lowlevel functions are Guile primitives
<ijp>for procedures from other modules, refer to them directly with (@ (foo) bar)
<ijp>nalaginrut: that's what (primitive ) is for
<nalaginrut>but I have to know when to generate (@ ...) or (primitve ...) code
<nalaginrut>If a function was realized as a primitive, it'll generate (primitive ...) or (@ ...) in tree-il
<nalaginrut>but the program needs a way to check it out, then generate
<ijp>there is a list of primitives somewhere
<nalaginrut>yes, I guess so, but I don't know the proper way to do it
<nalaginrut>I thing there should be an interface for it
<nalaginrut>s/thing/think
<nalaginrut>but I don't know what it is
<nalaginrut>that's why I asked
<ijp>right, but you did the classic XY problem thing
<ijp><fsbot> xyproblem -- when you want to do X, and you think Y is how, so you ask about Y instead of X. See <http://www.perlmonks.org/index.pl?node_id=542341> or <http://mywiki.wooledge.org/XyProblem>
<ijp>nalaginrut: there is a list in (language tree-il primitives), but I think it looks like guile can do some amount of detection for you
<ijp>see resolve-primitives!
<nalaginrut>I just need a simple (is-toplevel-defined? x) function, not to refactor all my design
<ijp>(note to self, never try and save people work)
<nalaginrut>And I can do it in some hack way, but I'd like to ask if there's a standard way
<nalaginrut>I'm not going to try to save others work if I don't really know what they want to do, and what context they encountered
<nalaginrut>alright, seems the-root-module is what I need
<nalaginrut>ijp: thank you very much anyway ;-)
<jmd>There's a guile construct analagous to switch/case in C - can somebody remind me of it?
<jmd> There's a guile construct analagous to switch/case in C - can somebody
<jmd> remind me of it?
<jmd>pp[s
<civodul>howdy
<civodul>jmd: 'case' or 'match' (from (ice-9 match))
<jmd>case uses eqv? so cannot be used with strings?
<Fulax>it cannot, as far as I know. From simple strings (e.g. one word), I usally convert them to symbols and then use match
<Fulax>otherwise I use cond
<taylanub>we don't have immutable strings yet, do we?
<taylanub>ah, literals
<jmd>ok thanks.
<taylanub>jmd: the ideal eqv? returns true for any two arguments which cannot be distinguished, e.g. two immutable strings consisting of the same characters, or if the two arguments are actually the same object; in practice this is impossible for procedures (might be the exact same algorithm implemented with different code), and can be difficult to implement for immutable data structures (recursively traversing them is not an
<taylanub>(eqv? must be fast), instead they would need to be de-duplicated to be the same object, as an optimization, when it's detected that the user created the same immutable structure twice). in Guile 2.0.11 this seems to be implemented for compiled files only, e.g. the following displays #t for me: http://sprunge.us/OZKe TL;DR: will never work for mutable strings, is unreliable for literal strings
<taylanub>tell me if this infodump was excessive :P
<jmd>taylanub: in #perl you would have been banned for it.
<taylanub>haha, mean. well it's silent here
<civodul>Fulax: 'match' can match strings, using equal?
<civodul>and lists, etc.
<jmd>I find it perverse that (program-arguments) has different semantics depending on how one starts guile
<civodul>like?
<jmd>guile -l prog.scm
<jmd>or guile prog.scm
<civodul>oh, what does it return in those cases?
<jmd>guile /tmp/pa.scm one two three
<jmd>("/tmp/pa.scm" "one" "two" "three")
<jmd>guile -l /tmp/pa.scm one two three
<jmd>("one" "two" "three")ERROR: In procedure open-file:
<jmd>ERROR: No such file or directory: "one"
<civodul>ah, interesting
<civodul>i usually use -e or some such
<civodul>and then there's also (command-line)
<jmd>Is there a standard "chomp" function. I always have to write my own.
<taylanub>jmd: read-line maybe?
<jmd>Err. I thought that just read a line from a port?
<taylanub>never mind .. this needs to remove trailing newlines only, right?
<wingo>string-trim-both
<jmd>wingo: Thanks.
<civodul>1. chomp, champ -- (chew noisily; "The boy chomped his sandwich")
<civodul>how can people understand Perl?
<wingo>that was practically a haiku
<ijp>use strict; my ($line, $noise); / how can we understand perl? / boy chomps his sandwich
<ijp>wingo: better?
<wingo>wow :)
<civodul>hehe :-)
<nalaginrut>poet?
<ijp>last christmas eve, I did a full length parody of "twas the night before christmas" about rms
<ijp>only the first stanza was any good
<nalaginrut>well, I'd like to see the rest of that poet/haiku ;-)
<davexunit>ijp: I thought it was hilarioius
<davexunit>hilarious, even.
<mark_weaver>nalaginrut_: don't generate 'primitive' tree-il forms yourself. let the resolve-primitives pass do it for you.
<mark_weaver>you don't have to worry about that part.
<mark_weaver>the scheme->tree-il compiler doesn't resolve primitives.
<mark_weaver>the problem is, the set of primitives changes from time to time.
<nalaginrut_>mark_weaver: thanks for reply! I'll take some time to response
*nalaginrut_ is feeding the baby...
<mark_weaver>okay
<mark_weaver>some of the tree-il constructs are only generated within the optimization passes. 'primitive' is one of them.
*nalaginrut_ is back
***nalaginrut_ is now known as nalaginrut
<nalaginrut>mark_weaver: I didn't generate (primitive ...) instr, but (call (toplevel ...) ...). I'm not sure if it's the same with what you said
<nalaginrut>after all, these details didn't in the manual
<mark_weaver>nalaginrut: why do you need to look up if something is defined at compile-time? that seems the wrong time to do that check.
<nalaginrut>I'm not going to check primitives, but I have to decide when to generate toplevel or lexical reference
<nalaginrut>that's why I want to know if it's a toplevel symbol
<nalaginrut>I think tree-il doesn't do that for me
<taylanub>AIUI anything not lexically bound should be assumed to be a toplevel -- guile allows defining them later, too. e.g. "(compile '(x) #:to 'tree-il) => #<tree-il (apply (toplevel x))>" when x is unbound
<nalaginrut>I think it may not my case, because I don't worry about if a symbol is undefined. If a symbol in certain context should be referenced as lexical one, it may get wrong result if I use toplevel instruction
<nalaginrut>so my understand is to decide which one to generate
<mark_weaver>taylanub is right. anything that's not a lexical is normally assumed to be a toplevel.
<mark_weaver>checking to see if something is bound at the toplevel is the wrong way to do it.
<mark_weaver>think about it: the same identifier can be bound both lexically and at the toplevel.
<mark_weaver>lexical bindings take precedence over toplevel bindings.
<mark_weaver>if there's a lexical binding, then use the lexical ref and set.
<mark_weaver>if there's no lexical binding, then use the toplevel ref and set.
<mark_weaver>whether there's a toplevel binding is irrelevant.
<mark_weaver>(at compile time)
<nalaginrut>so my understand from you is that I just use (lexical x x1) for it, right?
<mark_weaver>if there's a lexical binding, yes.
<mark_weaver>if there's no lexical binding, then you use toplevel-ref and toplevel-set
<nalaginrut>I have to try once again, because IIRC last time I tried the code is failed
<nalaginrut>so I want to try toplevel
<nalaginrut>I'll double check it
<mark_weaver>well, you use 'make-lexical-ref' and 'make-lexical-set' to create the tree-il nodes.
<mark_weaver>or 'make-toplevel-ref' and 'make-toplevel-set' for toplevel references
<mark_weaver>well, if you're using 'parse-tree-il', then just 'lexical' and 'toplevel'.
<nalaginrut>I'm using s-expr version
<mark_weaver>(though it seems a bit wasteful to create an intermediate sexp representation of tree-il)
<mark_weaver>but it's not a big deal
<nalaginrut>(lambda () (lambda-case ((() #f #f #f () ()) (call (lexical 1+ 1+) (const 1))))) Failed
<nalaginrut>I think it's fine in compile time
<nalaginrut>^ I mean sexp IR
<mark_weaver>one thing though: if you use 'parse-tree-il' on the s-exp representation of tree-il, then I think you won't be able to add proper source location information.
<mark_weaver>so error messages won't report the location in the source.
<nalaginrut>mark_weaver: Is my code wrong? It's fine when I change (lexical 1+ 1+) to (toplevel 1+)
<mark_weaver>I really think it's a mistake to use 'parse-tree-il' for this, because of the source location issue.
<nalaginrut>mark_weaver: thanks for mention it, it's fine for the vanilla code I think, could be changed in the future
<nalaginrut>s-expr is my fav so I picked it
<nalaginrut>mark_weaver: can you help me to find the error in the code I attached?
<mark_weaver>the second argument to 'lexical' must be a gensym, unique across the entire program.
<mark_weaver>(but the same when referring to the same binding)
<mark_weaver>in other words, in (let ((x 1)) (let ((x 2)) x)), each of those two bindings of 'x' must have different gensyms... and the reference 'x' must contain the gensym for the inner binding.
<mark_weaver>I'm sorry, I don't have time to help you debug right now.
<taylanub>nalaginrut: I don't see 1+ being bound lexically in that snippet?
<mark_weaver>nalaginrut: yeah, that should be a toplevel reference
<mark_weaver>nalaginrut: in general, I recommend looking at the tree-il that the macro expander produces.
<mark_weaver>nalaginrut: (use-modules (language tree-il)) (unparse-tree-il (macroexpand '(1+ 1)))
<mark_weaver>=> (call (toplevel |1+|) (const 1))
<nalaginrut>yes, I agree with all you, so that's why I want to check if it's toplevel
<nalaginrut>I know the error you pointed out, 1+ is toplevel
<mark_weaver>nalaginrut: you have it backwards. you need to check if it's lexical.
<mark_weaver>if it _is_ bound lexical, then use 'lexical'. if it's _not_ bound lexically, then use 'toplevel'.
<mark_weaver>whether it is top-level bound at compile-time is irrelevant. it tells you _nothing_.
<nalaginrut>ok, so the proper way is to check lexical
<nalaginrut>now my question is what's the best way to do it?
<mark_weaver>you have to keep track of the lexical bindings yourself. that's your job.
<mark_weaver>and for each lexical binding, you must generate a gensym. and when you see a lexical reference, you must determine which gensym it references.
<mark_weaver>and include that as the second argument to 'lexical'.
<nalaginrut>yes, I do that, so the best way is pass the env
<nalaginrut>I see
<mark_weaver>e.g.: (unparse-tree-il (macroexpand '(let ((x 1)) (let ((x 2)) (1+ x)))))
<mark_weaver>=> (let (x) (x-239) ((const 1)) (let (x) (x-241) ((const 2)) (call (toplevel |1+|) (lexical x x-241))))
<mark_weaver>notice how each of those 'let' forms that binds 'x' includes a gensym. and the 'lexical' ref within uses the inner gensym.
<mark_weaver>no two bindings can use the same gensym. the compiler assumes this.
<nalaginrut>ok, I saw it
<nalaginrut>btw, another question, how can I add a new customed primitive?
<nalaginrut>without changing the original Guile core
<mark_weaver>you can't do that without changing the VM and the lower levels of the compiler.
<nalaginrut>ok
<mark_weaver>you may need a runtime library, which you should probably put in a special module, and then use (@@ (nala runtime) proc) to reference it.
<nalaginrut>If I can't transfer all the AST node to Guile primitives, I have to use such library way
<nalaginrut>I guess it's slower than primitives, right?
<mark_weaver>nalaginrut: at some point we'll have cross-module inlining.
<nalaginrut>mark_weaver: could you more elaborate the term "cross-module inlining"?
<nalaginrut>alright, I can google it
<nalaginrut>I thought it's a new term you invented
<daviid>hello guilers, mark_weaver nice to see you appearing here :) how is the move going?
<mark_weaver>still in progress, in fact I have to go offline now to help more with it. ttyl!
<daviid>ok! ttl
<daviid>davexunit: i couldn't find much about clutter beeing used for game programming, but here what i found: http://curiositydrivendevelopment.blogspot.com.br/2013/11/windowed-gtk3-games-clutter-part2.html
<daviid>[know you're very busy at this time... but maybe in a near future...] i am curious and would like to know if you think what you do in guile-2d is feasible by customizing [guile-]clutter or not [and why], for the sake of learning [i have no knowledge what so ever in game programming]
<daviid>davexunit: if [when] you're interested here is the clutter api doc site [we bind 1.10.2, i'm working upon 1.12.2 hoping to bind till the latest in the future...: https://developer.gnome.org/clutter
<dsmith-work>ijp: Hah. Enjoyed that XY link. /me remembers greycat
<davexunit>daviid: hey! fsf mailing *over*
<davexunit>eagerly check your mailboxes in a few days.
<janneke>i find myself doing things like
<janneke>(define (fand . args) (eval `(and ,@args) (current-module)))
<civodul>janneke: this is terrible, "eval is evil"
<janneke> (apply fand '(some list with stuff))
<civodul>yeah
<civodul>you can use 'every'
<janneke>eg: '(foo foo #f) --> #f
<civodul>(every symbol? '(foo bar 42)) => #f
<janneke>hmm, and every identity probably?
<janneke> (every identity '(x y z 1))
<janneke>$30 = 1
<janneke>yay!
<janneke>thanks!
<civodul>you're welcome :-)
<janneke>didn't feel right...where would i learn this stuff if not on #guile?
<civodul>basically, everytime you think of 'eval', you should consider that something's wrong :-)
<janneke>:-)
<janneke>yes...to be honest, i didn't even notice the eval here...
<civodul>hehe
<janneke>i noticed the need for a function-like AND
<davexunit>janneke: take a look at the SRFI-1 API for all sorts of useful functions like this
<janneke>why does no-one need (apply and <list>) ?
<davexunit>I don't know if no one needs that.
<janneke>davexunit: thanks, thought i knew that one by now... ;-)
<civodul>it would seem natural, but 'and' is a primitive
<janneke>davexunit: well, it would exist then, wouldn't it?
<ijp>janneke: what does the following code do (lambda (f) (f (begin (display "launch the missiles\\n") 3)))
<janneke>at least, that how my newbie thinking goes
<davexunit>(apply and (map symbol? '(1 2 buckle my shoe)))
<davexunit>=> #f
<ijp>(yes, there is a point)
<janneke>ijp: not very much?
<janneke>davexunit: exactly, that would be nice ... now you need (every identity ...) or something
<ijp>right, but functionally, what can you tell me about it
<davexunit>janneke: hmm? that code should be valid. every is just shorter.
<davexunit>heading out.