
Schrödinger Error: Add a printf and the error is not there. Remove it and it is.

Update Racket and the error is gone

Excellent service Matthew, fix the error before I report it :)

actually, I just have the error in a different place now

tricky implementation question: I have a module that exports some syntax. In certain contexts, this syntax acts as a value. I’d like that value to have a contract attached to it, but I can’t figure out the right way to make my syntax play nice with the contract system’s module boundaries. the easy solution would be to define/contract the value that the macro expands to in my server module, but that isn’t the boundary I want.

Really stupid question time: has anyone used net/smtp
and net/qp
or net/base64
together?

I’m trying to send a message, but net/smtp
wants a list of lines, and it looks like the latter two encoding libraries produce a single bytes
with internal CRLFs

@leif I have on my TODO list the goal to upload code coverage results automatically (via the Travis script). I’ll remember to give you a ping if/when I implement the script.

thinkmoore: there’s something in syntax/parse’s experimental libraries that does that, forget its name

@jeapostrophe, @thinkmoore : it’s expr/c
http://docs.racket-lang.org/syntax/Library_Syntax_Classes_and_Literal_Sets.html#%28def._%28%28lib._syntax%2Fparse..rkt%29._expr%2Fc%29%29 There’s also wrap-expr/c
which I didn’t know about http://docs.racket-lang.org/syntax/wrapc.html#%28def._%28%28lib._syntax%2Fcontract..rkt%29._wrap-expr%2Fc%29%29

@georges-duperon thanks! that looks like exactly what I need

@georges-duperon Oh cool, yes, please do. :slightly_smiling_face:

It looks like - despite the documentation - handing a list containing the byte string produced by base64-encode
to smtp-send-message
works fine.

reply_broadcast messages not yet supported

Somewhere buried in my laptop is a work in progress package that provides base64 encoding with more options to support all the weird variations of base64

What’s there seems to work just fine for my purposes

or rather, wrap-expr/c is almost what I want but seems to cause the blame to be swapped

@thinkmoore what version of Racket?

6.9.0.2

hmm. I flipped the wrap-expr/c blame in 6.9, which IME is the Right Thing

but maybe that was a bad idea

let me try it with a small example

I’m surprised I didn’t add an @history
annotation :/

@thinkmoore: it sounds like you’ve hit the pathological case. wrap-expr/c is really intended to be used on macro arguments, but in older versions of Racket, the blame was not configured properly for that use case.

but in your case, it sounds like you want definition-like blame, which is the old behavior.

just saw that from playing with it in a small example… i’m trying to use it for a macro result unfortunately

seems like it should have an option

or two versions

(i’m implementing something akin to your multimethods implementation, but where methods have contracts)

probably adding an argument to wrap-expr/c is the right thing to do. I considered doing that when I changed it, but I decided I didn’t know enough to know what the interface should be.

that use case can probably motivate exactly what the argument should be like.

I would love to discuss this further, and I can also show you a workaround, but unfortunately I have to go, and I won’t be able to get back to this until late tonight.

I can deal with the weird error messages for now

talk to you later

if you look at the implementation of wrap-expr/c, you’ll find a contract combinator in the same module called blame-swapped/c or something like that.

if you just inline that into your code and apply it to your contracts, it will cancel out with the one inside wrap-expr/c, and you’ll get the blame you want.

@thinkmoore you might want to have a quick look at https://github.com/jsmaniac/polysemy which I published today. The online docs haven’t been built yet, so you’ll need to install it locally to read them till tomorrow. polysemy
allows defining identifier overloads. The first example in the docs defines ^
as a lexical token for a macro (a.k.a what you would normally use {~literal ^}
for), as the exclusive or match expander, and as two function overloads (one on numbers, which does expt
, and one on booleans, which does xor
). The four “meanings” are defined in four separate modules, and imported seamlessly without causing conflicts. The goal of polysemy
is to allow independent definitions of different meanings for identfiers (type, match expander, macros, function overloads, …), and to allow renaming the parts independently (to split or recombine meanings of one or more identifiers). For now the function overloads are single-dispatch, though, because it’s just a proof of concept.

@thinkmoore I’m more interested in the renaming / independent definition part than the multiple-dispatch part, but the latter is definitely something which I want to add later if the approach I took seems viable.

that sounds really interesting!

my current issues are about wanting to use a single id for both the method itself as a value, and as a carrier of compile time info

so that you can do (some-op with-some-args) but also (define-instance (some-op ….) …), where some-op has the necessary info to check various properties of the instance at compile time

which it sound like polysemy might help with

@thinkmoore what sort of properties do you try to check? Also, I suppose define-instance uses “instance” in the haskell way, toughly (so here it would define an overload for some-op which accepts the given arguments)?

it checks that the arities are the same, and that the instance dispatches on the the same number/position of arguments, and it also checks that there are no possible ambiguities (i only allow dispatch on a special class of struct-like things, so I know the possible subtyping relationships)

@thinkmoore In polysemy
I’m only checking that there are no ambiguities, based on the subtyping relationship (I hard-coded it for a few contracts for now, structs are not handled). The implementation mechanism is a bit crude: it uses a global hash table to track the possible overloads, and then checks at compile-time, when the id
is used, that for the set of overloads which are defined for this id do not overlap. The advantage is that I do not have the restrictions that @lexi.lambda’s multimethods have, namely that one of the dispatched-on types must be defined in the same module as the implementation. Also, there is no need for a centralized declaration of the method identifier.

The drawback is that it relies on name mangling: since require
and provide
only handle plain names, without anything like macro scopes, I simply define each overload using a mangled name, and the “main” identifier does a look-up when it is used.

sounds about the same, except that with multiple dispatch checking gets a bit hairy, so i wrote a little racklog program that both implements the dispatch and lets me query for ambiguities

Also, the overloads which can exist at the same time at a given point are more restricted: (foo TypeA Any) and (foo Any TypeB) cannot co-exist, because they overlap (whereas with @lexi.lambda’s restrictions, they could co-exist as long as they are defined in the right way). So we have different trade-offs, and I’m curious about the implications of each approach in practice.

@thinkmoore Ooh, racklog
… sweet :slightly_smiling_face: that’s a very nice idea (as long as you don’t hit a pathological case performance-wise, sigh).

yeah… haven’t profiled it yet, but since I :heart: logic programming I thought I’d give it a go….. >.> <.<

ah, that’s the kind of overlapping I check for

@thinkmoore One thing that I want to add later is the ability to have macro overloads (multimacros, if you will). As long as the syntax which they accept do not overlap, it should be allowed to define “the” macro in several separate modules. I’m half convinced that this could be cool, and half convinced that this could be a terrible idea :slightly_smiling_face: .

:ie: @thinkmoore, @georges-duperon: FWIW, my multimethods impl is basically a toy, and I would happily cede the package name to a better package. My bet is that nobody actually depends on that package.