IRC channel logs
2024-03-06.log
back to list of logs
<fps>dsmith: ah, that was probably it <fps>i wonder how to go about changing the default template to add some simple styling to all generated html <fps>and i wonder how i could "smuggle in" a changed version. i'm still a scheme noob, so any pointers would be welcome.. <fps>in the example haunt configuration there's a (use-modules ... (haunt builder blog) ...) so i guess the .scm file i linked to (blog.scm) defines that module.. <graywolf>Hello,Is the define-meta-command documented somewhere? <fps>hmm, is there a way to add an attribute to the top level html tag via SXML? <fps>this doesn't do the right thing: `((doctype "html") (@ (style "display: table; margin: auto;")) <dthompson>fps: you don't have a top level html tag in that example <fps>yeah, i think i got it :) <dthompson>((doctype "html") (html (@ (style "...")) ...)) <fps>dthompson: oh, you're the author of haunt. thanks a bunch for writing it :) <graywolf>Is the fact that (foo #:a 1 #:a 2) returns 2 for (define* (foo #:key a) a) something I can rely on or just an implementation detail? <wingo>so. i am looking at adding a racket-like `struct` form, probably named `define-record-type`, in the default environment. goal is to supersede srfi-9 by allowing record types to be defined declaratively, with space for keyword args for all interesting options, and with generated identifiers. <wingo>probably eventually supporting record syntax transformers as well. <wingo>anyone have thoughts on this? <wingo>also do we have a gitlab or something at this point <dthompson>generated identifiers, like for getters/setters? <rlb>wingo: so a superset of srfi-9, or...? <dthompson>in general I am on board with this. srfi-9 lacks some commonly needed features like setting a custom printer <wingo>dthompson: yeah. but also constructor and predicate. overridable, but probably will compute stem by trimming leading/trailing % and <> <wingo>rlb: yes. srfi-9 could expand into this. <dthompson>wingo: I'm not sure how I feel about that because of hygiene <rlb>wingo: and possibly not relevant, but I always wonder about introducing new bindings vs some kind of opt-in. <rlb>(for any given module) <rlb>But not arguing strongly against it or anything atm. <wingo>and of course as you probably are aware it would use the same record representation, b/c srfi-9 and r6rs and core guile records are all the same representation <dthompson>one of things I *really* disliked in my days doing ruby professionally, particularly with rails, is that *a lot* of identifiers were generated and it was so difficult to figure out where something was defined in a codebase. <wingo>dthompson: yeah i think it's a cultural issue -- hygiene is strictly supported, the derived identifiers are based on the scope of the record name <wingo>but yeah grepping for "wtf where is this defined..."; dunno <wingo>in racket they typically make the struct name the constructor, without any `make-` prefix or the like <dthompson>yeah, I've seen some examples of that. I'm mixed. <wingo>field accessors are structname-field <wingo>like right now defining a record type is... very ceremonious <dthompson>it seems silly to type it out manually when you're just following an established naming convention <wingo>it's like, you have to get into evening wear for dinner <dthompson>I like the idea of stripping <> from type names for things like printers <dthompson>like why is there a spaceship in my spaceship? <dthompson>most of the time my custom printers are just to get rid of that <dthompson>what kind of interesting options are you thinking of beyond printers? opacity? other things? <dthompson>it would be cool if constructors were more expressive so you could specify default args and such <wingo>supertypes. opacity. prefab (so we can read and write them). all the r6rs things <wingo>and then, i would like for (system foreign) to be able to nicely extend the define-record-type form to add a few others: read/write from/to bytevector, etc <wingo>you would have to opt into that one via (system foreign) of course <dthompson>I have spent a lot of time trying to approximate chez scheme ftypes as of late <wingo>but right now the syntax is too gnarly, there is no obvious place to extend with arguments <wingo>racket syntax has the advantage of a nice fixed prefix, it's (struct id (field ...) . options) <wingo>optionally with a supertype after id <rlb>I might really like solid and convenient support for immutable records, if that's feasible. <wingo>by default records would be immutable. they could be mutated under the hood via struct-set by index tho <wingo>struct-set! is just too powerful to expose to users :P <dthompson>I have a pretty gnarly macro called define-bytestruct (and a set of related macros) that allow defining structs that are a wrapper around a bytevector and an offset and provide structured access to the contents <rlb>...fwiw, clojure's defrecord defines a compact java class that masquerades as a map (but the named fields are much more efficient. But it's still a map, and of course immutable, so you can assoc/dissoc, etc. (if you assoc unrelated keys, they're handled, but if you dissoc a record "key", the type changes from the record type to a generic map) <wingo>dthompson: i think there's a place for that. i think there's also a place for a wrapper that copies out into a guile struct <rlb>Not that we'd be likely to want much of that. <wingo>depends on your model, specifically whether the bytevector is something whose lifetime you can control or not <wingo>so i suspect a define-bytestruct probably still makes sense. still would be nice to converge on the shape of the syntax <rlb>wingo: another thing I've wondered about wrt immutability (solid basic support for useful types) -- if we ever pursue that, is hashes. <dthompson>for me, it's all about a ref compiling down to a direct bytevector-*-ref call <rlb>i.e. you probably don't want to dynamically compute the hash of a giant recursive thing every time. <rlb>(wrt equality -- but that's a much bigger can of worms) <dthompson>all this to say, yes, would love a new define-record-type that was actually good :) <dthompson>and improvements to the ffi that allow for defining C-like structs in scheme a la ftype as well <wingo>rlb: ah i see what you mean. i guess a weak map can work as mechanism if you can be sure that the underlying data won't change <rlb>In the clj world, the record would just have a hash field I think, that might or might not eb computed lazily/atomically. That's what I did for lokke, fwiw. <rlb>Of course, our current hashing is a bit surprising (to me), and I know we've had some issues with it (and without immutability, you're more constrained), i.e. that our recursive structure (lists, etc.) hash value is just ad-hoc "sampling" of the subtree. <rlb>wingo: not sure it's feasible one thing we could consider is reserved/special methods, i.e. in the java world, that's (.hashCode thing). Then the equality predicates can favor that when it's available, and the tradeoffs are up to the type. <wingo>yeah. we could certainly add a hash field to all objects. not sure that would be a win though <rlb>Well if you just make it a method, then there might or might not be any storage. <rlb>But then you have the cost of checking for method existence in the dispatch predicates. <rlb>s/dispatch/equality/ <rlb>Make it an *optional* method I mean. <wingo>guile's pair hashes are quite terrible :P <daviid>dthompson: isn't guix doing this 'already', i mean some sort of define-bytestruct that effectively improve ffi struct (compiled time accessors to the struct elements ..)? <dthompson>daviid: if guix is doing it then I don't know about it. there's a bytestructures project out there but it didn't seem to do everything I needed when I looked at it. <dthompson>I don't know if anything that could be shipped in guile would do everything I need, anyway <dthompson>my bytestructs also allow for packing/unpacking bytevectors directly without a wrapper struct, which is something I need for efficiently filling gpu buffers but probably most people don't need <dthompson>it's an expansion of wingo's define-packed-struct from guile-opengl in several ways <dthompson>but it allows for structs, unions, arrays, etc. <dthompson>pointers for the C FFI case, recursive types, etc. <dthompson>the venn diagrams of bytestructs and chez scheme ftypes almost overlap. there's a couple things I don't have, and some things chez doesn't have to support the gpu use-case <dthompson>the pointer stuff is scary. it's the wild west once you need those. <wingo>yes. i want to add a keepalive construct to the compiler <wingo>otherwise it is almost impossible to use pointers safely :P <wingo>daviid: excellent link, thank you!!! <dthompson>daviid: ah yes, I had forgotten about this. this does a little bit of what bytestructs do. <wingo>that is some serious macrology <rlb>dthompson: I'm all in favor of making it at least *possible* to avoid "extra" allocations (or copying) in some of the cases I think you're talking about (even if it's some extra work -- i.e. as a lower level interface or whatever). <dthompson>I think the big missing piece with guix's define-c-struct (which they don't seem to need) is being able to compose structs together <dthompson>I don't see any code that allows the type of a struct field to be a type defined with an earlier define-c-struct form <rlb>You mean "inlining" them, storage-wise. <dthompson>ftypes allow this, and I followed their lead <dthompson>I made it work by copying a trick I saw wingo use in hoot <rlb>sounds like something I'd want, at least as an option. <dthompson>it's a lot more macrology to do this, but the result is composable types <dthompson>recursive types is yet another complication, but ftypes allow it so I wasn't gonna just let them win ;) <dthompson>probably also guix's define-c-struct doesn't generate code that's as optimizable, but they aren't fighting the gc tooth and nail like I am :) <dthompson>at least I think I see some stuff that will prevent unboxing optimizations in some cases <civodul>dthompson: re define-c-struct and “nested” structs, i think you’re right <civodul>it’s very much biased towards libc interfaces, which are usually rather simple <civodul>i’m not fond of bytestructures for FFI stuff <civodul>(at least not the way it’s used in Guile-Git) <civodul>(chickadee data bytestruct) looks very cool though! <civodul>dthompson: in Guile-Git it’s all run-time <dthompson>ah! that was my fear when I looked at it awhile ago <civodul>so it’s not much better than ‘make-c-struct’ et al <dthompson>make-c-struct seems to do a good amount at compile time <dthompson>bytestructs (I know, I know, too close to a name collision) does nearly everything at compile time <civodul>ah yes, define-c-struct does everything at compile time, that was the goal <civodul>the limitation is nested structs and things like that <dthompson>probably my bytestructs can be simplified some, but it's a close replica of ftypes syntax <dthompson>ftypes.ss is near unreadable imo, I think my code is at least a little better <dthompson>I don't consider it done, there's little things about the syntax and such that could be better. but it's working. <dthompson>between all of us, surely we could produce something for inclusion in guile that makes everyone happy :) <dthompson>civodul: chez scheme's "foreign types" API for their FFI <civodul>so define-bytestruct computes everything at expansion time, right? <dthompson>it generates a macro that does so when you use the bytestruct, anyway <civodul>but there’s run-time <bytestruct> record if i read it right? <civodul>i guess i should try it at the REPL :-) <dthompson>(bytestruct-ref <vec2> (x) my-vec2) will expand to code that type checks 'my-vec2' at runtime, and then does a bytevector-ieee-native-ref on the underlying bytevector with a precomputed offset <dthompson>so if you need an unboxed float, you'll have one <civodul>ACTION just tried: ,optimize (bytestruct-alloc <vec2> ((x) 2) ((y) 2)) <civodul>i could live without the intermediate <bytestruct> record <civodul>we should get this into Guile proper