IRC channel logs


back to list of logs

<guilenoob>hi all
<mark_weaver>wow, he was impatient for a response.
<mark_weaver>hi guilenoob!
<guilenoob>can someone give me pointer on how to use guile with geiser, I've used racket with geiser, but I can't make guile to behave the same way, I mean C-c C-a to enter module and change to REPL, I understand I need to define-module in source but I can't make it work.
<mark_weaver>I confess I've never gotten in the habit of using geiser much (although everyone tells me it's fantastic :), so I'll have to let someone else take this question.
<guilenoob>ok, thank you anyway
<mark_weaver>I have a shot-in-the-dark guess though: there's a configuration option for geiser to tell it which implementation you're using. if you have that set to 'racket', then some of the features might not work properly with guile.. but that's just a guess.
<mark_weaver>most of the guile experts are in europe, so they're all asleep now.
<dsmith>except jao
<mark_weaver>where does jao live? (he's the author of geiser)
<mark_weaver>jao: you around?
<dsmith>used to be spain. but he keeps hackers hours
<guilenoob>ok, can you help me with define-module?
<guilenoob>I guess you can export anything with (export X)?
<guilenoob>all examples in the reference are functions
<mark_weaver>yes, you can export any binding that way.
<mark_weaver>btw, what version of guile are you using?
<guilenoob>guile version 2.0.9
<guilenoob>Do i need the shebang on all files ?
<mark_weaver>no, only for scripts
<mark_weaver>here's an example of the preferred modern style for define-module forms:;a=blob;f=module/srfi/srfi-41.scm;h=3589b359d78d57ea3fface17047ec95a7638ba8a;hb=refs/heads/stable-2.0#l26
<guilenoob>Is load "file" encouraged?
<guilenoob>that seems a handy shortcut
<mark_weaver>load works, although the modern way to do that is to use the module system.
<guilenoob>I figured
<mark_weaver>the idea is that a module named (foo bar) must be in $DIR/foo/bar.scm, where $DIR is one of the components of %load-path (which is initialized based on the GUILE_LOAD_PATH environment variable plus some default directories)
<mark_weaver>and then you load the module using (use-modules (foo bar))
<mark_weaver>or, from the REPL a handy shortcut is to type: ,use (foo bar)
<mark_weaver>so, for example, I do: export GUILE_LOAD_PATH=$HOME/guile-modules in my .bashrc
<mark_weaver>and then I put my private modules in that directory.
<mark_weaver>but there are a lot of ways of doing it.
<guilenoob>I was trying wit (add-to-load-path (dirname (current-filename))) as the first expression in the module I wan to load
<guilenoob>what do you do to make "local modules" in your code
<mark_weaver>choose a unique prefix for your module names.
<mark_weaver>that's the usual way
<mark_weaver>there's only one module namespace in a given guile session, so you need to make sure that module names don't conflict.
<guilenoob>and you add your modules to the load path in the main file?
<mark_weaver>well, the best way is to install the modules somewhere that's already in guile's load path. so, when a guile program is installed, it installs its modules into $PREFIX/share/guile/site/
<mark_weaver>or, if you want to install local to a given user, then you install the modules in your equivalent of my ~/guile-modules/
<mark_weaver>think of it like installing shared libraries
<mark_weaver>however, if you prefer, you can use the 'add-to-load-path' thing at the top of a script.
<mark_weaver>(though I've never done that myself)
<guilenoob>ok i got that
<guilenoob>I was trying to use modules to organize my code, put all-files in same dir -> use files from main file
<guilenoob>which it seems would be using 'add-to-load-path ?
<guilenoob>or load "file"?
<mark_weaver>well, I think that's why 'add-to-load-path' was added, but I don't see how it can work well.
<mark_weaver>for one thing, if all the *.scm files are in a single directory, and you add that directory to the load path, then your module names have to be single-element module names, which is sort of like the equivalent of top-level domains like .com and .org
<mark_weaver>as for 'load', I don't think it'll work very well for actual modules.
<mark_weaver>for one thing, using 'load' to load a module will create the module, but it won't important the bindings from that module into the current module.
<mark_weaver>and it might even change the current module of the *importing* file to that of the *imported* file.
<mark_weaver>it's really not meant to work that way.
<mark_weaver>there are ways to make it work, but it will be kind of messy.
<mark_weaver>guile is flexible enough that you could implement something close to what you want, but it would be a new thing and not at all idiomatic.
<guilenoob>what is the guile way to organize code?
<mark_weaver>I think I already explained the preferred way of doing things, didn't I?
<mark_weaver>to recap: the usual way is to organize the code into modules. your private module names have a unique prefix. modules are installed somewhere in the %load-path (initialized from GUILE_LOAD_PATH and some built-in paths). put your modules either in the system paths such as $PREFIX/share/guile/site/ or in some user-local module directories that are in your load path.
<mark_weaver>i.e. they are organized somewhat similarly to how shared libraries are organized.
<mark_weaver>if it helps, the -L command-line option to guile adds a directory to the front of %load-path, and scripts can thereby add a directory to the front of the load path.
<mark_weaver>for that, you'll need to use the "meta switch", which allows you to pass multiple options to guile from a shebang. see
<guilenoob>nice, I think I can use this, thank you for your help.
<mark_weaver>no problem! happy hacking :)
<mark_weaver>feel free to ask more questions as needed.
<guilenoob>ok i think i get my error, not considering subdirectories
<guilenoob>(use-modules (foo bar) -> uses module in /foo named bar
<mark_weaver>yes, so if /home/foo/guile-modules is in your %load-path, then it will look in /home/foo/guile-modules/foo/bar.scm
<taylanub>ijp: Version 2 :P
<taylanub>Significantly cleaner and more sinsible I believe, though I might want to shorten it, I can get long-winded ...
<taylanub>I think it's now credible enough to post on the ML and ask for feedback. I suspect it might be a PITA to implement, and it touches the core of Guile a lot if I'm not mistaken, so perhaps it would be a 2.4 goal if anything.
<nalaginrut>hmm...the plan of 2.4 is out now...
<ijp>taylanub: among other things, you forgot about implicitly exported variables
<ijp>i.e. top level bindings introduced by exported macros should be immutable
<taylanub>ijp: I suppose they would be mutable through exported syntax ?
<ijp>well, not just top level ones, all levels really
<taylanub>Oh, you mean not mutating in the exported syntax, but having it give a binding one can use in any way one wants ?..
<taylanub>E.g. something like (define-syntax implicitly-exported-foo (identifier-syntax foo))
<taylanub>That's expected to work, no ? Inserting the variable `foo' in users of the syntax ...
<ijp>foo.scm (define-syntax-rule (foo x) (set! module-variable x))
<ijp>bar.scm (foo 1)
<taylanub>Well in that case the analyzer can see the `set!' on `module-variable' and consider it "possibly mutated", disabling optimizations, not much different from a usage of `set!' in side the module.
<ijp>taylanub: that makes no sense
<ijp>now compilation of bar.scm has to redo compilation of foo.scm
<ijp>sorry, misspoke
<ijp>consider the following
<ijp>foo.scm (define-syntax-rule (foo x k) (k x))
<taylanub>(BTW I see `set!' doesn't work on identifier-syntax ...)
<ijp>bar.scm (define-syntax-rule (baz v) (set! v 1))
<ijp>er, that should have been (foo k) earlier
<ijp>now if you do (foo baz), you have a mutation that was not there before
<taylanub>Oh shi-
<taylanub>OK, so there is a way to do what I thought one could do with `identifier-syntax'.
<taylanub>ijp: So that should either be an error, or work and make static analysis less powerful .. either way I don't think it hurts my proposal much but I'll revise it ...
<ijp>well, that one above is easy to fix
<taylanub>The analyzer could simply consider it "possible mutated" I suppose, akin to when it sees a `set!' call on it somewhere.
<ijp>the whole "In different words" part is really poncy
<ijp>I also find it hilarious that in your discarded ideas section you say "we dont want to mess with language semantics too much" when that is the whole point of the file
<ijp>taylanub: the point is, if you allow a macro to take a reference to another macro as an argument, then every use is "possibly mutated"
<ijp>it is a fiction to claim that "all essential run-time flexibility is retained"
<ijp>see the sentence below where you suggest a way to turn it off
<ijp>frankly, you haven't given a convincing rationale for why this is needed (even if I want something similar)
<ijp>(the ijp vocabulary police would also like to remind everyone that if you change the semantics of something, it is not an optimisation)
<ijp>hmm, I wonder if wingo&co would go for storing the source code in the object file
<taylanub>Excuses, had to go AFK.
<taylanub>The "in different words" part is me getting high on abstract thought. :P
<taylanub>Hrm, making stuff immutable and all is definitely significant changes in language semantics, you're right, I guess it's just that I find it a natural change to make module imports immutable ... whatever, drop the goal of not changing semantics.
<ijp><aside> it makes 0 sense to make imports immutable without making exports immutable </aside>
<taylanub>Hmm, why is that ?
<ijp>because now your constant isn't
<ijp>(define (loop x) (unless (end? x) (frob x) (loop (change x))))
<ijp>if foo is a constant reference, you only need to test that it is a function once
<ijp>if it can be mutated, it needs to be tested every time you go round the loop
<ijp>just because =you= can't mutate it, doesn't mean no-one else can
<ijp>(see C&C++ const references)
<taylanub>(All "essential" run-time flexibility is retained because what could previously be done via monkey-patching can now be done by swapping a whole module, though perhaps that's a silly way to put it becaues you can extend it to the point where the whole executable swaps itself for another?)
<taylanub>ijp: Yes, that's why I say it helps only with "intra-module" optimizations. Indeed that's perhaps very little gain, for the implementation complexity.
<taylanub>I'm not sure how the idea of making exports immutable would fit in the whole picture .. I think it's the same as my "static linking" idea ?
<ijp>basically, without immutable exports, you can't actually say that the "car" you imported is actually "car"
<ijp>simple as that
<ijp>it's car now, but 20 minutes from now, who knows
<ijp>if you go that route, then you need to be able to undo your optimisations later, like js implementations do
<taylanub>Yes, I understand, still you at least get guarantees on your private top-levels.
<ijp>most toplevels are not loops
<taylanub>You mean that that will only gain us very little optimizations ?
<ijp>you can inline, which is a start
<taylanub>The whole "part one" that is.
<ijp>I'm saying it only gives top level inlining
<ijp>you would get the same effect by writing all your procedures in a giant define-values
<ijp>(if and when we add that)
<ijp>moreover, you still need to explain why someone give up poking around in other modules
<ijp>you'd be better off just trying to implement it, and saying what happens, rather than trying to figure it all out beforehand
<ijp>this is why I want to implement my keybindings thing in emacsy
<taylanub>I was thinking it might be a deep and difficult change since I've read that boot-9 and such relies on module-fiddling ...
<taylanub>Perhaps we should postpone that and concentrate on the other idea first, that of static linking in the Guile compiler.
***goto is now known as anderson
<dsmith-work>Linking .go files. How cool is that.
<stis>hej på er guilare!
<dsmith-work>Hej hej
<stis>ijp: thx for taking the time to squash guile-bugs!
<stis>berndyn: that was supposed to be swedish!
<brendyn>stis: I guess they both have på and er?
***sethalve_ is now known as sethalves
<stis>I'm not so sure about Norwegian, more than it is very similar to Swedish.
*stis would like to help improve guile, but is so swamped up with logic programming :-)
*davexunit is trying to understand monads
*davexunit thinks it may be a useful thing for guile-2d but not sure
<davexunit>thank you ijp
<davexunit>I was secretly hoping that you would chime in :)
<ijp>monads = what you would get yourself if you decided to create a composition function for functions+(stuff that does effect)
<davexunit>I'm looking to model the state of a game that is changing over time.
<davexunit>I'll read this and see if I can make sense of it. I have some blockage that I need to get over.
<davexunit>that little lightbulb over my head hasn't turned on yet.
<ijp>you'll notice that at no point in that file do I use the word monad
<davexunit>but the end result is what would be considered a monad?
<ijp>if you get bored, scroll down and try and understand remove***
<davexunit>I see operations like lift
<ijp>davexunit: yes, and no
*taylanub loved
<ijp>I do not use the normal formulation of a monad, but one based on "kleisli arrows"
<ijp>which makes things simpler and easier to explain
<davexunit>taylanub: thanks!
<davexunit>for the people that actually understand monads: do you think that they would be useful in the context of a game (or simulation if you will) that accumulates state changes over time?
<davexunit>I want to learn about monads regardless, but I also don't want to have a hammer (monad) and start seeing nails everywhere.
<ijp>there is a weird technique some haskellers use, where they basically factor all IO out using "free monads", and then basically write their functions in a sort of state DSL
<ijp>I'm not sure whether it is really clever, or the stupidest thing I ever heard
<ijp>maybe both
<ijp>davexunit: you can certainly program a game that way, but I'm not convinced it's a good idea outside of haskell
<davexunit>ijp: yeah you're probably right.
<davexunit>I'm just trying to research some possibilities.
<davexunit>I have a sort of modes and buffers thing going on, similar to emacs.
<davexunit>a "scene" defines all the callbacks for a particular game mode, and a "stage" is the state of a game mode at the current time. in Emacs though, you have things like buffer local variables for managing the custom state associated with a mode.
<davexunit>I'm trying to figure out something similar. I've been experimenting with everything I can think of and haven't arrived at a good solution yet.
<gzg>davexunit: Were you able to get guile-sdl working adequately, or do you think you'll have to go SDL 2.x eventually?
<davexunit>gzg: it's working adequately. more adequately the more I work on it. SDL 2 will come with time.
<davexunit>I have a really awesome new REPL server on the back burner.
*gzg is excited to put sometime away to play with it, relatively soon. :^)
<davexunit>gzg: :)
<davexunit>just keep in mind that it's at version 0.1. there's plenty of rough edges. don't expect *too* much. :P
<gzg>davexunit: I gotcha, don't worry. :^)