IRC channel logs

2014-08-10.log

back to list of logs

<mark_weaver>optimus_swine: sure, but that's not what exceptions do. that's what the default exception handler does, but that's not a core part of the language.
<optimus_swine>mark_weaver, well, different langauges have different ways of dealing with a "dynamic type error" I guess, some raise an exception, some have no excpetion system, and some make the function return some sentinel value. Which does go to show the concept of a dynamic type error is considerably vguer than a static one.
<optimus_swine>You can even say that the function is perfectly well defined on that input as well, unless you want to say that raise is defined on no input whatsoever.
<mark_weaver>You are creating a strawman and then hacking away at it. The strawman you just created was some kind of mismash of all existing dynamic languages. of course things are going to be vague if you aren't talking about any particular language.
<mark_weaver>in R6RS scheme, exceptions are not so vague at all.
<mark_weaver>you can apply very precise semantics to them.
<mark_weaver>I guess you are saying that the fact that there are some other dynamic languages with different semantics somehow implies a weakness in every member of the set of dynamic languages.
<optimus_swine>Well, this at the very least demonstrates that "dynamic type error" means a different thing depending on the language and whom you ask.
<mark_weaver>so what?
<zacts>hi
<optimus_swine>Which is what I'm saying with that the concept is pretty vague.
<mark_weaver>the word "type" means a different thing depending on the language and whom you ask. does that imply that types in haskell are a vague concept?
<optimus_swine>The word "type" is then again prettyuseless yeah and people are typically warned not to use it.
<optimus_swine>Type in the sense of a static type referring to the type of an expression is an entirely different matter.
<mark_weaver>and exceptions in the sense of R6RS exceptions are also an entirely different matter.
<optimus_swine>The difference is that "static type" is an overarching concept that doesn't have an ad hoc definition pertaining to a single language but to basically everything in grammar theory.
<optimus_swine>Whereas dynamic type does not.
<mark_weaver>I'm not interested in defending the entire class of dynamic languages.
<optimus_swine>Which is defined ad hoc on a language per language basic, it's basically a type error if the language calls it a type error.
<optimus_swine>Honestly, that seems to be the issue, you see it as an "attack" that has to be "defended"
<mark_weaver>well, perhaps I've misunderstood. anyway, I have to go afk for a while. later!
<optimus_swine>Ah, I thought you had already returned
<optimus_swine>I'm very good at tying people to frivolous discussions abouts emantics. :')
<mark_weaver>I have a 3-year-old in the house, and that means frequent comings and goings...
<taylanub>honestly I'm feeling like I'm watching two people waste their time over nothing :P
<taylanub>optimus_swine: is there a summary of what you're trying to argue?
<ijp>taylanub: "frivolous discussion about semantics"
<taylanub>ah :)
<optimus_swine>taylanub, it's hardly something new, the age old thing that dynamic and static typing have nothing to do with each other and that whatever a dynamic type means is a different thing in each language basically.
<optimus_swine>As in, it's a type error if the language spec calls it a type error.
<ijp>a lot of words to say so little
<optimus_swine>Which I don't think r6 really does at one point.
<optimus_swine>It speaks of &serious exceptions adn violations etc.
<optimus_swine>ijp, hush
<optimus_swine>I am a couple of years older than you you know
<optimus_swine>with experience, you will see my ways.
<ijp>I couldn't care less if you were the king of siam
<optimus_swine>Well, since I am not the king of siam.
<optimus_swine>You couldn't not care less.
<optimus_swine>In fact, I am the finance minister of nigeria.
<optimus_swine>With a very interesting offer.
<ijp>have you considered peddling this tedious brand of sophistry somewhere else?
***cluck` is now known as cluck
<taylanub>uh, is this a bug?: (let () (define a a) a) => #<unspecified>
<taylanub>well it's probably just unspecified in the RnRS
<taylanub>hm, it's just "an error" in R7RS, as usual, but R6RS actually prescribes an exception
<taylanub>ah, didn't know that our `letrec' doesn't complain either, and found a bug (or wishlist) report about that, so never mind
<jao>Not very exciting in these MELPA days, but Geiser 0.6 is out -- https://github.com/jaor/geiser/releases
<ft>\\o/ Geiser.
<ft>Exciting mode is always exciting. :)
<jao>:)
<taylanub>apparently I have 0.4 :o time for an update
<jao>marmalade is still broken
<jao>at least for me
<mark_weaver>ah, geiser 0.6? time to upgrade the version in guix.
<mark_weaver>guix is still has 0.4.
<ijp>taylanub: if you felt language-lawyer you would argue complicance based on "_if_ an implementation detects such a violation"
<zacts>hi guile hackers
<optimus_swine>taylanub, yeah that bit me once too. In other implementations you can do things like (define a (+ a 1)) in <body>'s just fine, but apparently the spec doesn't say that you should.
<optimus_swine>Some of my code relied on it.
<optimus_swine>Well, that goes fine, what does not go fine is (define a (cons 3 a)) where a is a list, gives you (3 . <undefined>)
<mark_weaver>(define a (+ a 1)) is an error in an internal body. the 'a' in (+ a 1) refers the binding being made by that definition.
<mark_weaver>what did your code rely on it doing, and which implementation(s) did it?
<optimus_swine>mark_weaver, well, I sometimes defined functions that needed at least one argument like (define (f x . xs) (define xs (cons x xs)) ....)
<optimus_swine>Racket seemed to accept that.
<optimus_swine>As their letrec is actually r6's letrec*
<optimus_swine>One assumes it just translates an internal definition body to letrec, and thus letrec*
<mark_weaver>okay, but 'letrec*' still makes recursive definitions. the only difference is that the initializers are guaranteed to be evaluated in the order presented.
<mark_weaver>the 'xs' inside the cons still refers to the binding that (cons x xs) will be assigned to.
<optimus_swine>Hmm, maybe it has some other reason, I don't know. It worked however.
<mark_weaver>it does not refer to the outer 'xs'.
<optimus_swine>Admittedly, it doesn't work in racket any more as well trying it now.
<optimus_swine>Hmm, I'm fairly certain I used that idiom a lot but maybe I'm confused.
<mark_weaver>you can use it at the top-level, maybe that's what you're thinking of.
<optimus_swine>No, I'm fairly certain I used it inside function definitions to mark that a function needed at least one or more arguments.
<mark_weaver>if you want to do something like that, the proper way is with 'let', e.g. (define (f x . xs) (let ((xs (cons x xs))) ...))
<mark_weaver>if you can find any version of any major scheme implementation that does that, I'd like to know which.
<mark_weaver>I'd be very surprised if racket ever did that.
<mark_weaver>s/that/what you remember/
<optimus_swine>Well, I just use (define xs (x xs*)) now where xs* is in the formal spec
<mark_weaver>sure, that's fine of course.
<optimus_swine>To be honest, I'm not so sure any more seeing that I can't reproduce it.
<optimus_swine>But I could've sworn I had to edit like 10 files that used it.
<taylanub>I thought maybe optimus_swine's (define a (+ a x)) example was supposed to work like (let ((a (+ a x))) ...), which is to say refer to an 'a' in the enclosing/outer scope
<taylanub>that's very unconforming though ... anyway, just imagine internal defines as being letrec* and follow its rules and everything's fine
<optimus_swine>taylanub, well, that's what I thought it did for a long time.
<optimus_swine>I basically thought internal defines worked like top level defines.
<optimus_swine>Which is I guess in some weird way in between let* and letrec*
<taylanub>optimus_swine: even top level defines in a program shouldn't do redefinitions though
<taylanub>define acting like set! is just a convenience in the REPL where you can thus copy-paste your program into the REPL and not get errors because you pasted its old version there before; it offers you the convenience of just rebinding all the stuff that was previously defined
<optimus_swine>taylanub, well, in guile (define x 0) (define x (+ x 1)) (display 1) gives me 1 at the top level.
<taylanub>optimus_swine: but don't rely on it in a program, it's only guaranteed to work in a REPL
<taylanub>sequences of top-level definitions in a program can again be modelled with letrec*. a sequence "(define a _) (define b _) (some-code) (define c _) (define d _) (some-code)" would be like "(letrec* ((a _) (b _)) (some-code) (letrec* ((c _) (d _)) (some-code)))"
<optimus_swine>taylanub, this does remind me of the age old issue that someone at some point has to write an accessible tutorial about modern scheme, you basically have to read the specification to these kinds of things.
<taylanub>uhm wait, sorry, not
<taylanub>(because even 'a' and 'b' can refer to 'c' and 'd'...)
<optimus_swine>And the spec itself at times is worded in a uniquely vague style which assumes you already know how it works, it's written for implementors of course.
<taylanub>you're kind of right I think, though such issues of fudgy details can bite you in any language I think. for example consider JS's var hoisting, and its crazy object model, or consider Python normally only having two scopes (global and function-local) ...
<optimus_swine>Python's scope is bizarre and no where explained properly, I had to reverse engineer it.
<optimus_swine>I have the feeling that C is responsible in some way for Pthon and PHP's lack of proper treatment of the possiiblity of inner functions
<optimus_swine>But in the context of scheme, the only way to learn scheme seems to be to learn it slowly by hacking, every single bit of literature on scheme seems to be targeted to implementors always.
<optimus_swine>s/always/almost.
<taylanub>even the weirder parts of Scheme are surprisingly sensible, intuitive, and "the right thing" once you learn them, in my opinion. any complexity in Scheme tends to be the result of a fundamental complexity that a language has to address in *some* way, and where many try to hide it Scheme tends to address such problems directly. a good example is Scheme having let, let*, letrec, and letrec*, and
<taylanub>define and set!, where other languages mostly merge these together
<optimus_swine>Yap, that's what scheme does well for the most part.
<optimus_swine>General solutions rather than very specified ones.
<optimus_swine>Not having to define before you set also leads to weird bugs.
<optimus_swine>Typo in variable? It just gets created and nothing is reported.
<taylanub>hm, I never realized by the way that the top-level is this weird to model. I guess the only way to model it with letrec* is a big list of bindings in the letrec* where expressions which aren't defines in our original top-level are just bindings to throwaway variables, like (letrec* ((a _) (b _) (*ignore* (some-code)) (c _) (d _)) (some-code))
<taylanub>optimus_swine: by the way for already-programmers I wrote the following Lisp/Scheme intro: http://sprunge.us/ibhT I don't know how good my approach of teaching sexprs first is.
<optimus_swine>YEah, I saw that, might be a bit too abstract, I don't really know
<optimus_swine>taylanub, ever read a book like Real World Ocaml?
<optimus_swine>I feel that level might be approproate, it assumes some programming knowledge but does a good job of building understanding of Ocaml from the ground up and shows how to organize code in modules and all that good stuff.
<taylanub>I don't read books much. I think the only programming related book I ever finished was K&R, other than that half of SICP.
<optimus_swine>Well, it's on the internet, I read most of it. But it has a nice style I feel.
<optimus_swine>It also starts with a "guided tour" which is cool idea.
<optimus_swine>As in "You don't fully not to understand what's happening yet, but this is what OCaml looks like and what you can do"
<taylanub>is there a way to denote a DOCTYPE in SXML?
<paroneayea>mark_weaver: ijp: another route to doing the guile -> js route might be to have a more limited subset, which seems to be ther oute that clojurescript takes: https://github.com/clojure/clojurescript
<paroneayea>which seems to be an example of a lisp->js environment that's real and exists today (TM)
*paroneayea apologizes if everyone is getting tired of him talking about this :)
<mark_weaver>no, it's fine.
<paroneayea>I'd be kind of interested in working on this myself, though there are the constraints that a) I'm just now learning about compiler technology and b) mediagoblin takes a lot of my time right now
<paroneayea>but
<paroneayea>I might still be interested in helping
<paroneayea>though i don't really know where to start :)
<mark_weaver>the thing is, the core language isn't really the hard part.
<mark_weaver>I don't really see an advantage to just compiling a subset. if you are going to do that, might as well just use one of the numerous other existing scheme implementations on javascript.
<mark_weaver>anyway, I have to go afk very soon
<paroneayea>k
<paroneayea>mark_weaver: thanks for being patient with my exuberance for this thing that doesn't exist in guile-land ;)
<ijp>taylanub: yes, and no
<ijp>sxml->xml can't handle it, so you'd need to write it to a port beforehand
<ijp>but of course, you can do your own arbitrary sxml transformations with (sxml transform)
<taylanub>ijp: I see, thanks.
<taylanub>I wrote a tiny module that makes it less annoying to make and write HTML pages .. let me upload
<taylanub> https://gitorious.org/taylan-guile/html/
<saul>taylanub, what does define* do?
<ijp>saul: like define, but with support for optionals and keyword arguments
<taylanub>saul: accepts #:optional, #:key and #:rest
<taylanub>(#:rest is just identical to . AFAIK)
<saul>Thanks.