<amz3>yeah! got my web framework returning something :) <amz3>basicly it routes request to procedure based on path like any other web framework I know of <amz3>well, that almost all there is to it right now, another feature is that application are composed of sub-application <amz3>so in theory it's possible to have reusable apps <dsmith>mark_weaver, There was someone in here about 6-12 months ago that wanted to open some files that were near the location of his .scm module. He ended up walking the load-path for his module. <dsmith>mark_weaver, That probably won't help at all with the "relocatable" libguile though... IT's the load-path that needs setting in the first place! <ijp>(module-filename (current-module)) ? <dsmith>In the words of Emily Litella: "Nevermind" <dsmith>ijp, But that doesn't give you the full path. <dsmith>Just the "offset" from the load-path <ijp>hmm, what's the function to change module again? <ijp>that, but programmatically <mark_weaver>I think the concept of "the current module" is a fundamentally broken idea. <ijp>so, I can do (save-module-excursion (lambda () (gotomodule (foo)) *excute-code-in-context-of-foo)) <mark_weaver>but 'set-current-module!' is probably what you want. <mark_weaver>the first thing that macro expansion does is to "bake in" the top-level module into each identifier. <mark_weaver>from then on, macros can slice and dice these expressions, and then the concept of "the current module" makes no sense. <ijp>hmm, I was thinking current-filename might have helped, but with a quick few experiments, that isn't very helpful <ijp>mark_weaver: yes, it is problematic, but it's also been this way for a decade or so <mark_weaver>it makes sense to pass the module (a.k.a. environment) as an argument to 'eval' or 'compile'. <mark_weaver>it makes sense for the REPL to have a concept of "the current module". <ijp>hmm, I've never realised wondered this before, but what do we do about $variables at the repl? <ijp>do they get defined in the same module, or a separate one? <ijp>yeah, current module <ijp>it seems like when you e.g. ,m (ice-9 control) you can only see the $vars that were returned while in that module <ijp>but guile-user sees them all <ijp>no, that's not right either <cky>mark_weaver: Most likely, I'll be attending RacketCon this year. I've already booked my hostel accommodations, and will be booking my flight shortly...so, if you're going, hope to see you there. :-) <ijp>always visible, except for that one time I got an error <mark_weaver>ijp: cool! RacketCon is very close to where I live, so I guess I should make an appearance :) <ijp>hmm, I can't actually find the code where it defines those variables ***jao` is now known as jao
<ijp>I see, I was looking in the wrong place <ijp>it's in (ice-9 history) not under with (system repl ...) <ArneBab_>mark_weaver: the current module path could be very useful for easy to distribute games (just send around the folder). *ArneBab_ needs go go, though - just had a quick look at the backlog <nalaginrut>anyone help me about regexp? (regexp-split ".\\\\$\\\\{?([^}]+)?\\\\}" "a${b}c${d}asdf") <nalaginrut>I'm trying to implement a string template like python3 <nalaginrut>(regexp-split "[^$]*\\\\$\\\\{?([^}]+)?\\\\}[^$]*" "asdfaf${b}c${d}asdf${asdf}") <mark_weaver>what is the set of things that can be within the ${...} ? just variable names, or full expressions? <mark_weaver>also, I'd probably use irregex-replace/all instead of regexp-split <mark_weaver>(and omit the "[^$]*" at the beginning and end of your regexp) <nalaginrut>well, yes, I realized regex-replace/global is proper <nalaginrut>but seems I need to get the variable name from ${...} <mark_weaver>irregex-replace/all can accept a procedure that takes the match object and returns the substitution string. <mark_weaver>it might be easier if you put parens around the part of the regexp that contains the variable name. <mark_weaver>usually, regexp libraries allow you to access the parts of the string that correspond to parenthesized parts of the regexp. <mark_weaver>(irregex-match-substring <match-object> 1) is probably what you want, assuming that you put parentheses around the variable-name part of the regexp. <mark_weaver>you might consider using SRE instead of traditional string-based regexp syntax. SRE is much nicer. <nalaginrut>well, I've no idea how to pass the var-name as keyword, which could be taken by the template <mark_weaver>I guess the SRE would be something like '(seq "${" (submatch (+ (~ #\\}))) "}") <mark_weaver>'seq' could be replaced with ':' and 'submatch' with '$' if you prefer brevity. <nalaginrut>my plan is to return a lambda* which takes keywords as args, and the keywords should be the var-name within ${...} <nalaginrut>(define ll '((a 1) (b 2))) (lambda* `(#:key ,@ll) a) something like this <mark_weaver>(define alist '((test . "foo") (emergency . "bar"))) <mark_weaver>(irregex-replace/all '(seq "${" (submatch (+ (~ #\\}))) "}") "this is a ${test} of the ${emergency} broadcasting system." (lambda (match) (assoc-ref alist (string->symbol (irregex-match-substring match 1))))) <mark_weaver>I'll leave it as an exercise how to do it for keywords :) <mark_weaver>(also, that SRE should be precompiled using 'sre->irregex', for efficiency) <nalaginrut>mark_weaver: can't I use (lambda* `(#:key (a 1 #:a)) a) anyway? <mark_weaver>if the keyword is not a compile-time constant, then you can't use lambda* to get it nicely. <nalaginrut>well, I have to return a proc as proper interface for users <nalaginrut>I think lambda* would be better, or any better way? <mark_weaver>you'll have to so (lambda args ...) and then search 'args' yourself for the keywords. there's 'kw-arg-ref' in boot-9.scm, if you like, but it's fairly trivial to do anyway. <mark_weaver>(define var-subst-re (sre->irregex '(: "${" (=> name (+ (~ #\\}))) "}"))) <mark_weaver>(define (do-subst template . keyword-args) (irregex-replace/all var-subst-re template (lambda (match) (kw-arg-ref keyword-args (symbol->keyword (string->symbol (irregex-match-substring match 'name))))))) <mark_weaver>(do-subst "This is a ${what} of the ${adjective} broadcasting system." #:what "test" #:adjective "emergency") <mark_weaver>=> "This is a test of the emergency broadcasting system." <nalaginrut>I want to get the content of ${...}, but this doesn't seem to work " <nalaginrut>(iiregex-match-substring m 2) didn't parse the inner pares <mark_weaver>nalaginrut: you're compiling the SRE once for each call to 'make-string-template'. better to compile it just once ever. <mark_weaver>if "~" appears anywhere in the template string, it will break your procedure. why are you using 'format' ? <mark_weaver>well, just a suggestion. artanis is your project; do as you think best :) <mark_weaver>with that version "$${blah}" simply turns into "${blah}" with no substitution, as is proper. but "$$${blah}" turns into "$HI" if #:blah "HI" is passed. <mark_weaver>e.g. ((make-string-template "This is a $$$$${blah} $$$${blah} ${what} of the ${kind} alert system.") #:what "test" #:kind "emergency" #:blah "boring") <mark_weaver>=> "This is a $$boring $${blah} test of the emergency alert system." <nalaginrut>mark_weaver: thanks for reply , I just had lunch <mark_weaver>yeah, this is a case where SREs make the code much more readable. <nalaginrut>mark_weaver: if I parse 'dollar and replace it, I have to parse the string twice, right? <mark_weaver>replacing all of the $$ with $ in a first pass, and then replacing the ${...} in a second pass, doesn't work. <mark_weaver>because then $${key} becomes ${key} which then is substituted, but it shouldn't be. <nalaginrut>now I'm adding a new feature to support default value <mark_weaver>what's the purpose of using 'format' in a second pass? It's less efficient and less robust. <mark_weaver>it's less robust because (A) if there are any ~ patterns in the template, it will misbehave, and (B) you're assuming that the procedure passed to 'irregex-replace/all' is called in left-to-right order of matches, although that's not specified. <mark_weaver>and it's less efficient because you're needlessly constructing an intermediate string, and scanning the string twice instead of once. <mark_weaver>regarding A, try: (define tpl (make-string-template "${name1}, ~a I'm ${name2}")) and see what happens. <mark_weaver>also, try: (define tpl (make-string-template "${name1}, I'm ~${name2}")) <nalaginrut>hmm...I'm glad I created a nice honeypot for crackers ;-/ <nalaginrut>well, ~ could be fixed, but I've no idea about "~?" <nalaginrut>finally I'll generate a list contains all values <mark_weaver>you mean you want to be able to do (tmpl #:foo '(a b c)) ? <nalaginrut>assume name1==>"111" name2==>"222", the final value list would be ("111" "222") <mark_weaver>well, you're wrong about that, but I don't have any more time to explain it. <nalaginrut>sneek: later tell mark_weaver I don't see any way to handle it without 'format', if I use display, the code becomes more complex. For eval-order issue, I think you mean it will break the output of format with "~?". <sneek>Welcome back Chaos`Eternal, you have 1 message. <sneek>Chaos`Eternal, mark_weaver says: sorry I missed your messages earlier. Ping me next time you're on? <jmd>How can I test if something is a string? <taylanub>jmd: `string?'. Maybe read a Scheme intro and/or the Guile manaul. :) <jmd>To what should (pair? '()) evaluate ? <jmd>I need to parse a text file with guile. Are there any procedures to help such an applcation? <jmd>nalaginrut: Some god-forsaken adhoc thing. <nalaginrut>jmd: if it's plain text, maybe you need irregex, it's nice to use <nalaginrut>or if it's CFG, maybe take advantage of Guile's LALR <nalaginrut>unfortunately we don't have lexer, so you have to write a lexer if you need <jmd>What I could really use right now, is something like read-line but which recognises \\ as the line continuation character <jmd>How do I concatenate two strings? <nalaginrut_> (->sql select * from 'user where (and (= user "name") (> age 15))) <nalaginrut_> ;; ==> "select * from user where user=\\"name\\" and age>15;" <nalaginrut_>though result seems OK, the implementation code looks ugly ***linas_ is now known as linas
<sneek>Welcome back mark_weaver, you have 1 message. <sneek>mark_weaver, nalaginrut says: I don't see any way to handle it without 'format', if I use display, the code becomes more complex. For eval-order issue, I think you mean it will break the output of format with "~?". <shanecelis>Helping a friend out with MATLAB. I showed him how to do his own make-shift TCO with trampolines. He then asked, "What other languages do TCO?" ;) <mark_weaver>in scheme, it's not merely an optimization, but rather a core part of the semantics. procedure calls in tail position really are GOTOs with arguments. <mark_weaver>shanecelis: how do I build your emacsy-enabled webkit? <shanecelis>mark_weaver: It's baked into release v0.1.1 as an example. <dsmith-work>I tend to think of it as the "normal" kind of procedure call. It's only when it's not in tail position that *extra* stuff has to happen. <shanecelis>mark_weaver: so hopefully, wget ...; cd ...; ./configure && make && make run <mark_weaver>dsmith-work: yeah, another way to think about it is that procedure calls are always GOTOs with arguments, and that stack pushes happen when evaluating the argument to a procedure. <mark_weaver>at this point, I often find it painful to use languages without reliable tail calls. so many things become more awkward. <mark_weaver>sometimes I think I ought to add "GOTO with arguments" support to GCC, but it would be a lot of work just to learn what I need to know to get it done. <dsmith-work>mark_weaver: It can do that, but only in very limted cases. <mark_weaver>setjmp/longjmp are expensive enough that it would be pointless. <mark_weaver>and anyway, longjmp can only pass a single int value. <mark_weaver>and even if it did, it's not clear to me how longjmp would help. where would you do the setjmp and longjmp? <mark_weaver>one fundamental problem with TCO in C is that semantically, when one C function calls another, it is assumed that all the local (automatic) variables in the caller are still allocated during the call. <mark_weaver>so TCO can only be done if the compiler can prove that no pointers exist to the caller's local variables. <mark_weaver>what's needed is a way to say "I explicitly give the compiler permission to dump all the local variables before making this call" <mark_weaver>the rest is just implementation details about how to shuffle values on the stack and such. <mark_weaver>the other problem is the common "caller pops arguments" calling convention. <shanecelis>anybody on here, on twitter? I'm @shanecelis. I just want to make sure I'm following everybody. I gave #guile some shout outs in my talk for being super helpful. <dsmith-work>mark_weaver: Yeah, caller-pops make sense for printf, but the other way is much better for tail calls. ***sneek_ is now known as sneek
<dsmith-work>Ew. what about stuff like sparc with "register windows" insted of a stack. <mark_weaver>dsmith-work: yeah, I'm not sure off hand how SPARC's register windows would fit into this. <mark_weaver>I don't remember enough of the details of how they work; in particular, when they are pushed/popped to/from the stack <mark_weaver>My server is SPARC, but now that Oracle owns it, I've lost interest in that platform. I want to stay as far away from Oracle technology as I can. <mark_weaver>(after seeing them try to claim exclusive ownership over the Java APIs) <mark_weaver>It's too bad, Scheme has really gotten screwed by the fact that most modern calling conventions are geared towards making 'printf' a little more convenient, at the cost of making tail calls difficult. <dsmith-work>At the time (I was learning C) I though caller-pops was way cleaner and more symmetrical. But that was pre-ANSI C. <dsmith-work>Doug McLlroy was at an Ohio Linuxfest a few years ago. I shook his hand and expressed my thanks for making my life better.