<aeth>
On the other hand, svref only works on simple-vectors, not (simple-array foo (*))s, and (simple-vector *)s have to be (simple-array T (*))s
<aeth>
So they're considerably less useful than you think.
<aeth>
Usually if you care enough to let the compiler know it's a simple array you also are probably using (unsigned-byte 8)s or single-floats or whatever.
Bike has quit []
<aeth>
Even if svref worked, that wouldn't give enough information: the type of elements held and the length are pretty important. So you basically have to declare when doing array stuff.
<aeth>
s/array stuff/optimized array stuff/
quipa_ has joined #lisp
quipa has quit [Ping timeout: 272 seconds]
<v0|d>
my $.02vref is vector ref, aref is array ref? arrays can have dimension > 1.
<White_Flame>
svref = simple-vector ref
<aeth>
v0|d: A vector is a 1D array. A simple-vector is a 1D simple-array (simple means not adjustable, with no fill pointer, and probably a few more things that help compilers out) that holds elements of type T. This second part makes the concept of simple-vector alone a lot less useful than it could otherwise be.
thinkpad has joined #lisp
<White_Flame>
it makes the addressing of the slot easy to find
<White_Flame>
for the implementation
<malice_>
What are you favorite Common Lisp libraries? I was thinking of cool common lisp libraries lately and was curious what are peoples' favorites.
<aeth>
v0|d: A simple-vector is incredibly niche. A simple-array can be common in certain use cases. So you basically always have to use aref (n-dimensional arrays) or elt (sequences, including vectors) and give enough type information to ungenericify the accessor.
<aeth>
There is afaik no vecref
<v0|d>
aeth: no worries, I never took CL types seriously.
<aeth>
v0|d: CL arrays are actually one of the stronger points for its types, especially when working with numbers (or characters)
<aeth>
This simple-vector stuff is just (imo) an incredibly stupid part of the standard.
<malice_>
aeth: why?
<malice_>
(why do you consider them stronger points for types, especially with numbers/chars)
<White_Flame>
in ye olde days, the calculation of the slot address within an array was much more expensive, and there were far fewer non-boxed values
<aeth>
malice_: You can have 0, 1, 2, ..., array-rank-limit dimensional arrays of character, simple-character, bit, and (not standard, but in almost every implementation) (unsigned-byte 8). You also normally can have fixnum, [un]signed-bye for 16/32/64, single-float, double-float, (complex single-float), and (complex double-float).
robotoad has quit [Quit: robotoad]
<White_Flame>
plus, there was no type inference anyway
<aeth>
malice_: You can access all of this with aref, and you can define a type to greatly simplify the rather messy syntax (that would be a bit less messy if simple-vectors could be specialized for types like simple-arrays)
<aeth>
You can specify length or you can use * to work on any length.
<aeth>
Seems like one of the stronger array offerings in a programming language, especially if you're working with numbers or characters.
<aeth>
malice_: Oh, and if an implementation doesn't support it, it will just become a generic T array instead of failing, so you can safely use (complex double-float) everywhere unless you rely on its checking for errors.
resttime has joined #lisp
<malice_>
I see. Thanks
<aeth>
And in some implementations, :type in a struct slot will help out the type inference. So now these mostly-useless, legacy, pre-CLOS stuff (structs) have a purpose.
<aeth>
i.e. Have to pass around several arrays, but with a known length and numeric/character type? Put them in a struct with the appropriate array type as the struct slot :type and then non-generic AREF will be used and things will be much more efficient. Just declare/check-type/whatever the one struct's type, not the dozen arrays.
<aeth>
(And, in fact, it probably can tell it has to be that struct type, and thus the result has to be that array type, by the accessor's name.)
<aeth>
This is the secret to using CL as a Fortran.
<malice_>
:)
<resttime>
Been trying to get back into lisp again manipulating parsing/manipulating data from a csv
<resttime>
Got confused on floats being truncated until I figured out that it's because reads were doing it on 'single-float
<aeth>
malice_: oh one more thing, I should emphasize that most of this relies on optimizations permitted but not required by the standard, but that it will run (slowly) on implementations that don't implement all of those optimizations
<resttime>
(setq *read-default-float-format* 'double-float) makes things work out
<malice_>
resttime: Nice!
<malice_>
aeth: sure
<pjb>
as would 1.0d0 instead of 1.0
wilfredh has quit [Quit: Connection closed for inactivity]
<jasom>
resttime: there is also the parse-float library which is probably better for untrusted inputs
uint has quit [Quit: Lost terminal]
<resttime>
pjb, it was on reads so something like (read-from-string float-as-a-string)
<aeth>
always write 1.0d0 or 1.0f0 (or 1.0l0 or 1.0s0) because you don't know what a prior system set that global to when asdf is loading your code
<malice_>
there's also safe-read to make read safer, instead of parsing floats
<resttime>
jasom, might have tried that lib but it kept truncating as well
<pjb>
also, remember that floating point formats are different in different programming languages. So if you need to parse eg. JSON data, which uses the Java format, don't use CL:READ!
<resttime>
This was the value I was trying to parse "-87.381425", and oh I guess I dunno how to properly parse floats from a csv
<resttime>
Errr, parsing from a csv that is which is being read by line
<resttime>
Is there a proper way to parse floats that keeps precision?
<jasom>
resttime: with you can do (parse-float some-string :type 'double-float)
<jcowan>
Why are simple vectors niche? I don't understand that. They are a very handy data structure with different tradeoffs from lists.
<pjb>
resttime: you can transform it into a ratio: "-87.381425" --> (/ 87381425 1000000) #| --> 3495257/40000 |#
<jasom>
resttime: that will parse it as a double float; if you want to parse it as an arbitrary precision decimal, perhaps someone else can recommend a library for that; I've not had cause to use decimal libraries in lisp
Jesin has joined #lisp
<resttime>
jasom, oh missed the &key arg
<resttime>
pjb, makes sense
nirved has quit [Quit: Leaving]
<didi>
aeth: In the past, declaring the type of a variable as FIXNUM has made wonders to my program, but I must confess, unless large integers are definitely ruled out from the domain of the variable, I feel uneasy.
Jesin has quit [Quit: Leaving]
fikka has quit [Ping timeout: 246 seconds]
<jasom>
didi: on sbcl unless you set safety to 0, it will at least be just a runtime error.
<didi>
jasom: Ah, good to know, thank you.
<malice_>
resttime: I wouldn't recommend using ratios though
<malice_>
they are much slower than floats
Bicyclidine is now known as Bike
<jcowan>
"A is slower than B, so use B" is not always good advice.
<malice_>
sure
<jcowan>
Those features are in the language for a reason, after all; someone needed them.
<malice_>
Doesn't mean that those features are good
<malice_>
though ratios are fine. They just aren't too fast, so while this approach is pretty straightforward and simple, it's also much slower. Just something to have in mind.
<malice_>
I mean, depends on your definition of broken. Definitely something to watch out for, but when dealing with floating numbers you should be aware of that.
<malice_>
and for most applications this is not an issue anyway
resttime has quit [Remote host closed the connection]
cylb has quit [Ping timeout: 272 seconds]
resttime has joined #lisp
<didi>
I once performed trigonometric operations in series, lots of them, with hilarious results. :-(
<equwal>
The production code https://github.com/thephoeron/let-over-lambda loads up, including other macros dependent on it. When I try to run it in SLIME I get 'g!whatever doesn't exist' kind of errors.
<pjb>
Then you need to define g!whatever.
<equwal>
Yeah defmacro! is an extension of defmacro/g!
<equwal>
Do you understand that the point of defmacro/g! is to do automatic gensyms for |g!<name goes here>| variables?
<pjb>
Yeah.
<equwal>
So a trivial thing like (defmacro/g! test () `(list ,g!a ,g!b)) doesn't work in the REPL, as it expands to (DEFMACRO TEST () (COMMON-LISP:LET () `(LIST ,G!A ,G!B)))
<pjb>
You can debug macros using macroexpand-1 and using *macroexpand-hook*.
<Bike>
I can't think of any reason that it would expand differently in the repl.
<Bike>
it looks like it is expanding for you, so it's probably not a package mistake.
<equwal>
It expands but that expansion is bogus.
<Bike>
Right. I mean I don't see why you'd get a bogus expansion in the REPL and a non bus one from compile-file.
<Bike>
Could you try a quick test file with a defmacro/g! to see if that works.
<Bike>
er, wait.
<Bike>
You said "including other macros dependent on it" but I don't see any
<Bike>
defmacro! expands into defmacro/g!
<Bike>
defmacro! is used in the file, i see
<Bike>
still, a test file might be good, or testing dlambda or something
<equwal>
nlet-tail works for me
<equwal>
(nlet-tail fn ((n 0)) (if (= n 10) n (fn (1+ n))))
<equwal>
----> 10
<Bike>
and the test file?
mejja has quit [Remote host closed the connection]
<Bike>
like just define something trivial with defmacro/g! and see if it works.
<equwal>
(defmacro/g! test () `(list ,g!a)) --> 'undefined variable: G!A' in the compilation dialogue.
maximjaffe has joined #lisp
Mr-Potter has quit [Ping timeout: 268 seconds]
elfmacs has quit [Read error: Connection reset by peer]
<Bike>
okay, so things are at least consistent.
<Bike>
are you sure that the defmacro/g! here is the same as the one in this lol file? Like you didn't define your own defmacro/g! as a test?
<equwal>
Maybe it is my init file, I'm going to go sbcl --no-init
quipa_ has quit [Ping timeout: 268 seconds]
<equwal>
Well that isn't it either.
<Bike>
so you restarted sbcl and still got this?
<equwal>
Yeah I ran it from console with --no-userinit since I have an init script. I used all code from the book in my test file.
<Bike>
This seems like a good opportunity to mention that defmacro/g! is nonconforming code due to how flatten works, which is why the ersion on github there does special things for sbcl
<Bike>
You can see the one on github has ((typep x 'sb-impl::comma) (rec (sb-impl::comma-expr x) acc))
elfmacs has joined #lisp
<Bike>
A few years (i think) ago SBCL changed its implemntation of the ` reader macro to expand into special structures instead of list structure
<Bike>
this breaks flatten, which expects all code to be in conses
<Bike>
every few months somebody comes in here and asks why defmacro/g! doesn't work in sbcl, and this is why
<equwal>
It doesn't work even when you use the production code that does that thing you mentioned.
<Bike>
are you sure? i'd expect the patch to work.
<Bike>
but if it doesn't, eh.
<equwal>
I'm sure about it not working.
<equwal>
I guess flattening lisp code in a macro is a bad idea, who knew?
<Bike>
defmacro/g! is trying to do something outside the normal semantics, so it's kinda hairy.
dale has quit [Quit: dale]
elfmacs has quit [Ping timeout: 245 seconds]
orivej has joined #lisp
elfmacs has joined #lisp
<pjb>
equwal: you can flatten code in a macro, but do it correctly.
<equwal>
pjb: In what way? all: Why not implement a reader macro with the same functionality?
nicksmaddog has quit [Ping timeout: 250 seconds]
elfmacs has quit [Ping timeout: 245 seconds]
maximjaffe has quit [Ping timeout: 240 seconds]
<pjb>
equwal: indeed, that would be a good way to do it in a conforming way.
<equwal>
And I'm off to the races.
<pjb>
Or you could not use backquote. list list* cons append are perfectly good to build sexps.
resttime has quit [Quit: Leaving]
<equwal>
You mean in the (defmacro/g! ()...) forms? That would ruin the convenience of it a bit.
<pjb>
not at all.
<pjb>
Most of the time, you don't win much by using ` compared to normal operators.
<equwal>
I think when it is important (like with nested `) it is a big deal no?
<Bike>
pjb is kind of contrarian.
<equwal>
He can go on writing his macros without ` if he wants.
resttime has joined #lisp
<Bike>
well, he doesn't actually.
<equwal>
I'm sure he doesn't.
<Bike>
anyway, if you really want to do this my first suggestion is to not want to do this, but failing that i guess a reader macro would be the way to do it
<equwal>
Why do you think I should not want to do this?
<Bike>
because the g! stuff makes bindings etc implicit instead of explicit, making things a bit more confusing for readers
<pjb>
Notice how much clearer and concise your macro becomes!
wanz has joined #lisp
<pjb>
There's no secret: when you introduce functional abstractions, you get clearer, and more maintainable code.
<equwal>
Yes.
dddddd has quit [Remote host closed the connection]
robotoad has joined #lisp
elfmacs has quit [Ping timeout: 272 seconds]
elfmacs has joined #lisp
elfmacs has quit [Ping timeout: 272 seconds]
resttime has quit [Remote host closed the connection]
elfmacs has joined #lisp
d4ryus has quit [Ping timeout: 252 seconds]
elfmacs has quit [Read error: Connection reset by peer]
moei has joined #lisp
<aeth>
didi: Integers are tricky because CL handles them properly so if you want to keep them in bounds in a simple and general way you probably want to manually implement C-style wrapping modulo arithmetic, like (mod (+ x 42) (expt 2 n)) and otherwise you need to do some fancy things
<aeth>
didi: single-float and double-float are really simple because CL handles stuff like nan and inf by erroring
<aeth>
(or you can turn that off in an implementations-specific way)
<aeth>
So you don't have to establish that you won't overflow
notzmv has quit [Ping timeout: 245 seconds]
jkordani has quit [Read error: Connection reset by peer]
elfmacs has joined #lisp
ryan_vw has joined #lisp
anewuser has quit [Quit: anewuser]
resttime has joined #lisp
rumbler31 has joined #lisp
<White_Flame>
equwal: when I wanted quasiquoted source code to be cons-traversable, I turned to fare-quasiquote
elfmacs has quit [Quit: WeeChat 2.3]
pierpal has quit [Quit: Poof]
pierpal has joined #lisp
<LdBeth>
How can I let arithmetic overflow?
uint has joined #lisp
arescorpio has joined #lisp
rozenglass has joined #lisp
Roy_Fokker has quit [Read error: Connection reset by peer]
rumbler31 has quit [Remote host closed the connection]
<aeth>
Most of the rest just have a fast path for SBCL and a slow path for everyone else
<aeth>
Now (since August) in quicklisp.
slyrus1 has joined #lisp
slyrus has quit [Ping timeout: 268 seconds]
slyrus1 is now known as slyrus
slyrus1 has joined #lisp
ryan_vw has joined #lisp
vlatkoB has joined #lisp
elderK has joined #lisp
<elderK>
Hey guys, what is the perception of Fukamachi's "Package per File" style?
<no-defun-allowed>
Fukamachi kinda doesn't do any documentation so it's probably not associated with good practice.
<no-defun-allowed>
Also, cl21 is yuck. So, erm, probably guilty by association for being bad.
<elderK>
:( I wish the specifier in (check-type ... spec) was evaluated
reverse_light has joined #lisp
<elderK>
Also, is there any good reason not to have &optional and &key parameters?
<elderK>
A more important question: How are docstrings meant to be aligned? I see some people who have the first line indented, and subsequent docstring lines at the left margin. Then I see some people who align the subsequent lines with the starting " of the first.
slyrus1 has quit [Quit: slyrus1]
rippa has joined #lisp
arescorpio has quit [Remote host closed the connection]
<elderK>
Interesting. I wonder what the differences are between DECLAIM and PROCLAIM.
<elderK>
So far, all I seem to grok is that DECLAIM has compile-time effects
<beach>
Good morning everyone!
<beach>
elderK: &optional and &key parameters slow things down.
<beach>
elderK: Yes, DECLAIM acts at compile time.
<aeth>
elderK: as far as multi-line docstrings go, I do "\n
<aeth>
Only downside is emacs doesn't format it properly unless you do "\n\n and then format it and then delete the second \n
<aeth>
(actual newline, there is no \n literal in CL)
<aeth>
elderK: I'm not sure whether \n" or " is better for ending it, though
<beach>
elderK: You can use #.(format nil "...") then you can use ~@ at the end of lines and align the following lines with the rest.
<elderK>
beach: For docstrings?
<beach>
Yes.
sauvin has joined #lisp
<elderK>
beach: Is it worth declaiming like, a defgeneric? It seems useful to like, specify the parameter types. But, not so useful wrt to the return type, since the kind of thing that the GF returns depends on the method :|
<beach>
I never do.
<elderK>
So, you'd declaim ftype for the methods, not the generic?
<beach>
elderK: I think you should put the docstrings in a separate file anyway. They are not meant for the person reading the code, so they are noise to that person.
<beach>
No, I rarely declare any types.
<elderK>
Even for structure or object slots?
<beach>
Correct.
<beach>
I don't use structs.
<beach>
Can't trust the semantics.
<beach>
SICL will have structs, but they will be implemented just like standard objects.
<elderK>
Cant trust the semantics?
doubledup has joined #lisp
<beach>
It is undefined behavior if you redefine a struct.
<beach>
Whereas for standard objects, it is well defined.
doubledup has quit [Client Quit]
Elephant454 has quit [Quit: ERC (IRC client for Emacs 26.1)]
<beach>
elderK: If you have a standard class (what you get when you use DEFCLASS), and you have allocated instances of that class, it is well defined what happens to the instances when you redefine the class. Not so with structs.
dale has quit [Quit: dale]
shifty has joined #lisp
<jackdaniel>
ECL does something what makes sense, otoh ccl and ecl are careless with structures
<beach>
What does ECL do?
<jackdaniel>
second, I'll paste issue I'm reporting here
<jackdaniel>
I meant: SBCL does something what makes sense
<beach>
Since I don't use structs, I am in no rush to decide how they should behave in SICL.
resttime has quit [Ping timeout: 252 seconds]
cylb has quit [Ping timeout: 252 seconds]
wanz has quit [Quit: wanz]
dale has joined #lisp
resttime has joined #lisp
dfsg has joined #lisp
resttime has quit [Client Quit]
<aeth>
beach: What (imo) makes structs useful in SBCL is the :type of a slot. It's not just a check-type, it informs the type inference so if you had a (simple-array double-float (4)) as the type, it won't do bounds checks and it will know it's a double-float (with limited boxing avoidance)
dfsg is now known as resttime
pillton has quit [Ping timeout: 256 seconds]
rozenglass has quit [Remote host closed the connection]
ryan_vw has quit [Ping timeout: 245 seconds]
nanoz has joined #lisp
shka_ has joined #lisp
<jackdaniel>
afaik slots in defclass have type too
<jackdaniel>
(and some implementations at a high safety level try to enforce these types)
hugh_marera has joined #lisp
robdog_ has joined #lisp
buffergn0me has quit [Remote host closed the connection]
buffergn0me has joined #lisp
<no-defun-allowed>
IMO structs are a lower level packing of values, like C structs rather than C++ objects so they're just fast...er
d4ryus has joined #lisp
nirved has joined #lisp
<aeth>
jackdaniel: The types are enforced in a check-type or assert way in defclass. The types are useful for type inference in defstruct in SBCL.
<elderK>
See, this is why I'm interested in using the :type stuff.
<elderK>
I also figure it could conceivably help the compiler like, do its job better.
pierpal has quit [Ping timeout: 244 seconds]
<beach>
elderK: It is amusing, though, to see how much time some developers spend on low-level optimization, but then they are totally incompetent when it comes to designing efficient algorithms and data structures, so the gain a small amount of execution time with their optimizations, but then they lose a lot on the design.
razzy has quit [Ping timeout: 244 seconds]
<beach>
elderK: I find it a lot more rewarding to spend my time designing efficient algorithms and data structures.
nanozz has joined #lisp
nanoz has quit [Ping timeout: 246 seconds]
<shka_>
good morning
<beach>
Hello shka_.
dale has quit [Quit: dale]
<elderK>
Morning shka_
<shka_>
elderK: from my what i experienced so far, type information helps greatly for numeric code in SBCL, but it is less significant for everything else
<shka_>
but, type safety is helpful for keeping code bug free
<shka_>
*regarding optimization
<shka_>
actually, with proper hints, sbcl can produce efficient numeric code
<shka_>
but it is rather tedious to write :-)
xkapastel has quit [Quit: Connection closed for inactivity]
hugh_marera has quit [Remote host closed the connection]
pierpal has joined #lisp
wanz has joined #lisp
zigpaw has quit [Quit: Vanishing into darkness in 1..2..3...]
chip2n has joined #lisp
wanz has quit [Quit: wanz]
<robdog_>
Depending on your situation... dont forget that buying a faster computer, is one of the cheapest optimizations.
<no-defun-allowed>
except when you're not deploying to that computer
<robdog_>
thats the situation :)
<no-defun-allowed>
"buy a better 'that comuputer'" you say, well if it's someone else's computer you're rating the rates become absolute garbage after the first few low ones usually
<robdog_>
i always tell my boss that..and i get new computers
<no-defun-allowed>
1. go on userbenchmark.com 2. inspect element, remove all % signs
<robdog_>
send the boss a link to one of those Harvard productivity reports..and BANG, you have 3 new 4k monitors coming
<no-defun-allowed>
3. boss, the FooBar 1100 is 5 times faster than the FooBar 1000 can i have it
wanz has joined #lisp
<no-defun-allowed>
4. get FooBar 1100, then get FooBar 1200 when that comes out using the same method
<robdog_>
YOu always get the new stuff..pass down the old machines to the Jr's
<robdog_>
recycling..its good for the world
<no-defun-allowed>
true
<aeth>
robdog_: "Buy a faster computer" doesn't work anymore unless your workload is parallel
<no-defun-allowed>
also use buzzwords "if i get a FooBar 1200 i can utilise neural network blockchain mapreduce to make emacs start googol% faster"
<aeth>
In fact, your shiny new "faster" 32-core computer probably is slower than your old 2014 quad core in single-threaded stuff.
<aeth>
Because heat.
<aeth>
So you actually make some things slower by upgrading now
<robdog_>
just stick a sleep() in your code..when your boss is over your shoulder asking why aint you coding... just say your computer is too slow
<aeth>
robdog_: optimizing compilers got rid of the best ways of actually doing that in practice
<aeth>
in the 90s people put loops doing nothing in their code all of the time apparently
<no-defun-allowed>
pmap gang -- i mean, single core performance in the mid range is slowly improving but multicore is happening more nowadays
<aeth>
just delete a 0 when you need to speed up
<aeth>
Depending on the implementation this can work: (dotimes (i 10000000000))
<aeth>
(we need more zeros these days)
<no-defun-allowed>
it does here
<robdog_>
these "new computer" tricks dont work, if your boss is aeth.. you will still be using the 386... but with math coprocessor! hahaah
<no-defun-allowed>
takes 4.6 seconds
<no-defun-allowed>
apparently though it's using dark magic since that single thread of dotimes is using 4x as much CPU time
<aeth>
robdog_: If you're writing something for end users instead of for servers, maybe you should be developing/testing on the average machine rather than a high end one.
<aeth>
That would actually draw a good line with where to optimize and where not to.
<robdog_>
i know aeth..that is the "situation"
<no-defun-allowed>
i think my machines are cursed, my phone spat out a message despite having wifi off and TIME has been acting up
<jackdaniel>
I know you did put some lisp form in there accidently, but this is still offtopic
zigpaw has joined #lisp
<robdog_>
We all have only 24 hours in a day.. so OUR time is the most precious and most expensive.. so i DEVELOP on the fastest machine i can get my hands on.. then profile on the target machine
<no-defun-allowed>
so erm, has anyone done much work with fuzz testing in CL?
<aeth>
no-defun-allowed: yes
<no-defun-allowed>
how'd it go?
<aeth>
But I think mostly for implementations, i.e. fuzz testing CL rather than fuzz testing in CL
<no-defun-allowed>
oh i see
random-nick has joined #lisp
cage_ has joined #lisp
doubledup has joined #lisp
wanz has quit [Remote host closed the connection]
groovy2shoes has joined #lisp
zigpaw has quit [Quit: Vanishing into darkness in 1..2..3...]
kajo has quit [Ping timeout: 252 seconds]
kajo has joined #lisp
kushal has quit [Remote host closed the connection]
angavrilov has joined #lisp
kushal has joined #lisp
zigpaw has joined #lisp
robotoad has quit [Quit: robotoad]
chip2n has quit [Remote host closed the connection]
jochens has joined #lisp
<elderK>
Guys, If I have some integer, and I manipulate it with ldb and such, are the "bits I extract" guaranteed to be like, two's complement? I get the feeling it is.
robotoad has joined #lisp
<beach>
Yes.
<elderK>
Fantastic!
<beach>
... but with infinite precision.
pierpal has quit [Quit: Poof]
pierpal has joined #lisp
<beach>
A negative integer starts with an infinite number of bits that are 1.
Mr-Potter has joined #lisp
_heisig has joined #lisp
<elderK>
Yup
<elderK>
It's funny how using languages like C really screw with your sense of what is normal. Like, having to parse integers from a binary file, say, byte by byte, and reconstructing the value, feels very.... horrible. Searching online, I found many people who were seriously GRRRR about this.
<elderK>
But the thing they don't seem to realize is: Reading some bytes into a buffer, then casting to access that in C, is not safe or sane either.
<shka_>
elderK: but there is a library for doing this!
<elderK>
And not portable, for obvious reasons. Even if you had code to "flip bytes" to handle endianness, you'd still be playing with fire since there's no guarantee that some "pointer deref to integer" would even be safe, since some architectures do not allow unaligned reads.
<elderK>
So, really, people who gets pissed about this are simply pissed because their favorite shortcut doesn't work
<elderK>
And that shortcut is debateably shit anyway.
<elderK>
shka_: Which? There seem to be several :) fast-io by rpav, etc. Awesome as it is, it doesn't do what I want.
<elderK>
Besides, right now, I *want* to make my own stuff, for learning purposes :)
<shka_>
oh, ok
<shka_>
i was going to suggest cl-binary
<elderK>
:) I've been looking at that, too
<elderK>
The thing is, what I'm building anyway, I want to extract stuff from vectors. Not from some stream. Most of what I've seen, assumes you are always reading things from a stream.
<elderK>
The idea is that you'd load the shit into a vector, then parse it from there.
<elderK>
With wrappers that allow you to do it "stream wise."
<shka_>
flexistreams exists
<shka_>
well, have it your way :-)
<elderK>
Right. I imagine that allows you to say, have a vector acting as a backing for some stream.
<pjb>
elderK: almost no C programmers knows C at all.
<shka_>
pjb: otherwise they would stop being C programmer?
<elderK>
I consider myself a pretty good C programmer. But a lot of that isn't because I'm a C programmer, it's more because of a background writing system software. So, you become aware of a lot of "gotchas" that most people never realize.
<pjb>
elderK: they know some language looking vaguely like C, and that C compilers happen to be able to compile most of the time, but by basically generating lots of undefined behavior.
<elderK>
Like the alignment issue mentioned earlier.
<pjb>
The fun with clang!
<pjb>
shka_: probably indeed.
<elderK>
shka_: What does flexistreams provide? :)
<pjb>
elderK: the ability to switch between binary and text stream.
<pjb>
ie. you can (list (read-byte s) (read-char s) (read-byte s) (read-line s) (read-sequence byte-vector))
lumm has joined #lisp
<elderK>
Is that what is known as a bivalent stream?
<shka_>
also, in-memory streams
<shka_>
including making stream around vector
<pjb>
elderK: and yes, flexistream can also read from byte vectors, just like with-input-from-string can read from strings. It has WITH-INPUT-FROM-SEQUENCE WITH-OUTPUT-TO-SEQUENCE.
<pjb>
elderK: yes, bivalent streams.
_heisig is now known as heisig_
pierpal has quit [Read error: Connection reset by peer]
random-nick has quit [Ping timeout: 250 seconds]
<makomo>
elderK: another somewhat crazy thing is that C/C++ don't even guarantee how signed integers are represented -- it might be two's complemement, but it also might be one's complement, sign and magnituted, or something completely arbitrary
<pjb>
This is what let's C run on so many different computers.
<makomo>
yep
<makomo>
ones'* :-)
<pjb>
At least, unsigned are binary :-)
<makomo>
yeah, thank god
heisig is now known as Guest54457
Guest54457 has quit [Killed (leguin.freenode.net (Nickname regained by services))]
heisig_ is now known as heisig
Guest54457 has joined #lisp
random-nick has joined #lisp
<jackdaniel>
I'm sceptic whenever god had much to do with it
<SaganMan>
lol
<no-defun-allowed>
Are there any resources on extending swank/slime? I have an idea for a somewhat more useful &body autodoc.
<jackdaniel>
source code is the most faithful resource in this case, check out contribs directory
<jackdaniel>
swank is common lisp part with interfaces defined separately and implementations defined per-lisp implementation
<jackdaniel>
and it is hosted in a separate directory named swank. slime is of course elisp, many things are well commented (but not all)
<no-defun-allowed>
Okay, I shall do that tomorrow.
<no-defun-allowed>
I don't think there's much to modify on the elisp side fortunately, I just want it to emit different text when it's going to highlight a &body variable of a macro.
<no-defun-allowed>
Eg, (cond &body (conditional &body progn)) or something that exposes the syntax a bit more. It'll lose terribly for LOOP and LOOP but for most macros it should be okay.
<no-defun-allowed>
*that will be derived from a list made by myself, introspection would be a pita.
shifty has quit [Ping timeout: 245 seconds]
<no-defun-allowed>
Goodnight now.
<cage_>
good night!
pjb has quit [Ping timeout: 252 seconds]
pjb has joined #lisp
ggole has joined #lisp
arbv has joined #lisp
lumm has quit [Quit: lumm]
lumm has joined #lisp
easye has quit [Remote host closed the connection]
fikka has quit [Ping timeout: 272 seconds]
ski has quit [Ping timeout: 264 seconds]
jmercouris has joined #lisp
<jmercouris>
how do I specify a defmethod with a deffault value?
<jmercouris>
beach: like can I have xyz have a default value of "abc"?
<jmercouris>
or did I get the order wrong?
<beach>
You can do that with &optional parameters, but not with required ones.
<beach>
And you can't specialize on &optional parameters.
<jmercouris>
It is optional, sorry I didn't put that in the example I gave
<jmercouris>
Ah damnit
<jmercouris>
I assume the same is true of key parameters?
<beach>
Yes.
<beach>
You can specialize only on required parameters.
<jmercouris>
what a shame, this would have made things way simpler
<jmercouris>
I'm sure there is some reasoning behind it though
<beach>
Otherwise, the method would have to be invoked in order to determine whether it can be invoked.
lumm has quit [Ping timeout: 276 seconds]
<jmercouris>
not sure I follow you there
<beach>
Not important. Forget about it.
<jmercouris>
Ok
<jmercouris>
I would be interested if would take a look at my source at some point for Next
<jmercouris>
I'm sure you'd have a lot of ideas about what is wrong :D
<beach>
Quite possibly.
<jmercouris>
and how I've fundamentally misused and abused a lot of code lol
<jmercouris>
maybe after this release, which is looking to be quite close now, the MacOS port is almost done, as is the GTK one
Bike has joined #lisp
<jmercouris>
just working on changing the Lisp core to handle everything being asynchronous now between the UI and the rest
<jmercouris>
so have been modifying everything to use continuation passing style
<elderK>
Hey jmercouris! How are you doing?
<elderK>
:P I have something I want to show you guys, for feedback but I'm kinda scared :P lol
<jmercouris>
elderK: I'm doing well
<jmercouris>
elderK: how about yourself?
<jmercouris>
elderK: any feedback you get is an opportunity for growth, not a challenge against your ego
<elderK>
Not bad :) Just finished the first part of the ... thing I've been building.
<jmercouris>
when you view it that way, everything is much more pleasant
<jmercouris>
what have you been building?
<elderK>
jmercouris: Agreed. That's generally how I (try) and operate: It's all about the code, not about my ego. I want to write the best Lisp I can. And the only way I can improve, is from feedback.
<elderK>
jmercouris: I've just been writing some utilities to let me perform binary IO. See, I want to build a program to let me explore and parse the ext2 filesystem.
<elderK>
I saw that there were several such utility libraries around. But, I wanted to make my own, for learning :D
<jmercouris>
ext2 file system? are you working on legacy systems?
<jmercouris>
sounds like an interesting and challenging project
<jmercouris>
I probably would have chosen C myself for such a task, but why not Lisp
<elderK>
Another side project I have going, is writing a small kernel for some classmates. It's been a long time since I wrote a driver for ext2 and such, so, I wanted to explore and ... unrust.
<jmercouris>
a driver? are they called drivers for file systems?
<jmercouris>
I didn't know that
knobo1 has joined #lisp
<elderK>
A friend of mine, a youngster, is very interested in kernels. He's been messed with XV6, which is what they use at Uni to teach "kernels." But he's very dissatisfied. I can understand why, too, based on what he's shown me. Anyway, I'm on break now since finals are done. So, I decided to work on a small kernel for him to learn from and play with.
<elderK>
He's not yet at the stage where he could dive into the Linux kernel and really get anything out of it.
<elderK>
:) Also lent him a ton of my deadtree books, too. I hope I get them back.
<knobo1>
Funny that I don't know how to make a string with some content, that is not a literal with just one function.
<elderK>
:P They cost me a lot of money like, ten years ago.
<jmercouris>
elderK: are you a professor?
<elderK>
Nope.
<elderK>
Just another hacker :)
<jmercouris>
knobo1: not sure what you are saying
<elderK>
I'm just older than most students - I'm 31.
<elderK>
knobo1: You could use format to make a string?
<pjb>
jmercouris: you can define a wrapper function providing defaults: (defmethod m ((a integer) (b string)) (list a b)) (defun f (a &optional (b "abc")) (m a b))
<knobo1>
elderK: yes I could.
<elderK>
knobo1: I'm afraid I don't understand what the problem is? :)
<jmercouris>
pjb: so a function generator? or a macro?
<knobo1>
elderK: I was thinking to complicated, yes.
<pjb>
a function.
<knobo1>
Or not complicated enough
<knobo1>
I guess princ would do it right.
<jmercouris>
pjb: ah, I just re-read your code, I understand now
<knobo1>
or format
<elderK>
jmercouris: Anywho, it's crazy. This friend of mine is say, 21. And he's interested in this stuff, which is great because so few students around my Uni's CS department give a shit about anything low-level. I was writing toy kernels when I was around 17. I worked on a variety of "systems" for many years. That interest kind of entered "hold" when I entered the workforce though :)
<jmercouris>
maybe I should, I'll think about it, for now I just made two functions
<jmercouris>
elderK: Why should anyone care about anything low level? I'm personally only concerned about the given abstraction level that I'm working at
<jmercouris>
If I can't treat my abstraction as opaque and clearly specified, then I'm not working on a higher level, and I may as well have no abstraction at all
<elderK>
jmercouris: How to put it. People who got As in "Computer Architecture" don't know what the stack is or why it is useful. Nor do they know about interrupts.
<jmercouris>
elderK: Did you graduate university?
<elderK>
Many students don't even see the point in learning about say, red-black trees or hash tables :(
<jmercouris>
I'm not sure where you went to school, but our experiences have been quite different, to say the least
<jmercouris>
not only do they teach everything you've talked about at my school, they teach it in racket
<robdog_>
i dont consider red/black trees or hashtables to be low level
<elderK>
No. But I'm working on it. I dropped out many years ago, and entered the workforce. But, not having a degree was causing issues in (some) companies. So, I decided to finally get my degree.
<jmercouris>
I also find it hard to believe that any school would omit such basic curriculum
<pjb>
every level is low level for higher abstractions!
<elderK>
robdog_: They aren't. But they are important, and this is the kind of stuff that the students just, don't care about. They should.
<jmercouris>
I didn't go to a super prestigious school or anything, but I can't imagine that the worst school would not teach those things
<pjb>
that's the point of layers; there's always a lower level, and a higher level.
<pjb>
It's all turtles down under, but also above.
<jmercouris>
is there ALWAYS a lower level though?
<robdog_>
assembly = low
<jmercouris>
I'm not sure I buy that, there must be an absolute lowest point of abstraction
<robdog_>
everything else, is high level
<jackdaniel>
below assembler there is machine code
<jackdaniel>
below machine code there are electronical circuits
<elderK>
jmercouris: Anywho. What I really mean though, the kicker for me, is that there are very few students (two, in fact) who are interested in the stuff I am. That's really it :P
<elderK>
There's a lot I intend to add to this. But, before I did, I wanted to get a feel for whether I'm on the right track or not :)
<jackdaniel>
for starters putting some kind of README at toplevel is expected, so one could get a grasp what the project is all about
<jackdaniel>
as of asd file, to avoid nested modules, you may put top-level option :pathname "src/" and then you may avoid whole "module" nesting, just put :file clauses normally
<elderK>
Cool :)
<jackdaniel>
you are inconsistent in packages.lisp, you have (:use :cl #:k.utilities.binary), make everything #:foo, like (:use #:cl #:k.utilities.binary)
Essadon has joined #lisp
<elderK>
Okay, can do :)
<beach>
The FORM of DESTRUCTURING-BIND should be indented 4 positions compared to the DESTRUCTURING-BIND form itself.
<jackdaniel>
default method for initform-for doesn't make much sense, how is NIL a suitable form for initializing values of type XYZ which you do not know about
<beach>
Comments to be aligned with code take two semicolons.
<elderK>
beach: Ah, I thought it was. slimv must have mesed i tup.
<beach>
Top-level comments take three semicolons.
<elderK>
Ah yeah, slimv did mess it up :(
<beach>
I don't think I am up to following the program logic at this point. I need a break.
<elderK>
Okay? Well, thank you for taking a look. I have fixed the destructuring-bind and comments.
<elderK>
I have also removed the default method for initform-for.
<jackdaniel>
if this is for learning, then ignore this comment, but did you have a look at a library "binary-types"?
<elderK>
I wanted to try and build my own utilities for doing the binary IO. Just, to get a feel for things. And learn how to do it properly.
scymtym has quit [Ping timeout: 268 seconds]
robdog_ has quit [Remote host closed the connection]
<elderK>
:) Right. I have made all of those changes :)
jochens has quit [Remote host closed the connection]
pchrist has quit [Quit: leaving]
pchrist has joined #lisp
pierpal has joined #lisp
knobo1 has quit [Remote host closed the connection]
lumm has quit [Quit: lumm]
lumm has joined #lisp
<elderK>
Thanks for taking a look guys :) I will study binary-types for awhile now. It looks very nice
jmercouris has quit [Ping timeout: 245 seconds]
lumm has quit [Client Quit]
razzy has joined #lisp
lumm has joined #lisp
jmercouris has joined #lisp
<elderK>
jackdaniel: Do you have any advice on how to learn CL, well, more effectively? How did you start off?
<jmercouris>
elderK: I have some advice, have patience :)
<pjb>
elderK: I learn programming languages by reading the reference, and by trying out each language element in small programs. But I hear it's atypical, most people can't learn a language reading an arid reference or specification.
<jmercouris>
there is a lot to learn, and no single individual is a master of all of Lisp
<jmercouris>
there are so many Lisps, implementation details, gotchas, and the spec is huge
<pjb>
jmercouris: well, yes, it's possible to master al of CL. All of emacs, it's possible if you live 120 and start at 3.
<jmercouris>
lol, then yes
<pjb>
elderK: don't worry, it'll take you at least ten years anyways.
<elderK>
pjb: Other than experimenting and reading other people's work, I'm not sure how to ensure that that I improve.
<hypnon>
elderK: reading Keene is a quick way to get into CLOS. otherwise a lot of hacking will get you there. what makes lisp in general different, is the freedom. the solution space for any given problem is very large in lisp. explore that space in as many ways as you can. there's not really any "right way" to program in CL ime.
makomo has quit [Ping timeout: 245 seconds]
<elderK>
hypnon: :) Aye. I guess that is also what makes it a little overwhelming to start off with.
fikka has quit [Ping timeout: 252 seconds]
<jackdaniel>
elderK: me? I've started contributing to open source projects
<jackdaniel>
first easy tasks then progressively harder
<jackdaniel>
thanks to that I've made a fair deal: professional guidance of smart people for my time
<jackdaniel>
(guidance in form of advices, peer reviews, corrections etc)
josemanuel has joined #lisp
<jackdaniel>
in fact I'm still following this patter of learning (reading good resources like books is also helpful)
<jackdaniel>
pattern*
<elderK>
It sounds like a good way to be part of the community.
<elderK>
Maybe I should try it out :)
<elderK>
What kind of projects do you contribute to? How did you find like, things to do when you first started? Like, issues that were at your level as it were?
<jackdaniel>
I'm too shy to brag about that stuff. biggest projects I work on are ECL and McCLIM. As of things, you often find annoyances when you i.e follow PCL (i.e slime chokes on something, then you go to report it or see if it is reported)
<jackdaniel>
and if such task is within your reach, you try to solve it (if you have time)
<elderK>
pjb: Mezzano definitely interests me. I know of Froggey and have been aware of his work for many years. Long before his OS was called "Mezzanine."
<elderK>
jackdaniel: Would it be useful to start with small contributions like, loading Alexandria raises a few warnings. It would be neat to fix them.
<random-nick>
Mezzano has a channel on freenode, #mezzano
<jackdaniel>
also going through the issue list of biggish projects used by community is a good place for look
<jackdaniel>
does alexandria raise a few warnings? never heard about that
<jackdaniel>
there is an easy task on log4cl if you look for a starter
<jackdaniel>
revert some commits to use semaphores from bordeaux-threads (which were recently added there)
<jackdaniel>
oh, I see someone tackled it already, I need to review it
<jackdaniel>
then nvm
<trittweiler>
elderK, warnings are not raised but signalled in Common Lisp. ;) And note that a warning signalled during compilation means that the compilation failed. So I really doubt that any warning is signalled when compiling alexandria. :)
<jackdaniel>
if I had to guess, it is asdf having problems with its legacy
<pjb>
It's always possible to write trivial libraries.
<elderK>
scymtym: Thank you :)
<pjb>
elderK: or: com.informatimago.common-lisp.cesarum.ascii or com.informatimago.common-lisp.data-encoding.data-encoding etc.
<didi>
pjb: I worry about the behavior of mathematical functions when fed infinities. For example, do all SIN functions return the same value when fed infinity?
<pjb>
didi: why would they?
<pjb>
They should signal an out-of-domain error.
<didi>
pjb: I don't know. But if all did, a trivial library would be feasible.
<didi>
pjb: That's fine.
<didi>
Another example: (+ inf 1). Is it an error or is it inf?
<didi>
inf is more useful, but still a choice.
<pjb>
I would say, just define a proper type hierarchy for sets of numbers + infinity and sets of infinities, and define proper arithmetic operations on them.
<didi>
Indeed.
<pjb>
This library can use NAN infinities for infinite decimals if they are available but it would use other representations if not, and it would have to have integer and real infinities too, (and I'd assume complex infinities).
<didi>
Then I argue we are out of trivial libraries domain.
<pjb>
Probably, for complex, you'd have (rho,infinite) in polar representation.
<Bike>
it seems like the magnitude does increasing as you get off the real line, so maybe it actually is infinity on a riemann sphere or something.
<pjb>
the point is that lim_[x->∞]( sin(x) ) is not determined.
ryan_vw has joined #lisp
xkapastel has joined #lisp
AeroNotix has quit [Ping timeout: 276 seconds]
rjid has joined #lisp
<elderK>
Gosh, most Lisp I read has lines well in excess of the 80 margin
<beach>
Not mine so much.
<elderK>
Reading "binary-type" right now. Nice code. But the defmacro part for define-binary-record and stuff is pretty crazy
<elderK>
I mean, they obviously knew what they were doing, far more than I do. But, I could have tried to break the macro down. It's this gigantic thing.
<elderK>
I guess they had reasons.
<pjb>
Bike: for complex, just revert to the fundamental formula: 1+e^ip=0, therefore sin(x)=(e^ip-e^-ip)/2i
makomo has joined #lisp
<pjb>
By the way teaching maths is also done very badly. If you started by teaching complex numbers and 1+e^ip=0, you could cover 4 years of elementary maths in one semester…
<pjb>
(list (frame-text-width) (frame-text-height)) --> (3180 1794) ; in pixels…
Lycurgus has joined #lisp
<pjb>
elderK: that said, the indenting conventions of CL makes it very possible to use proportional fonts for its sources (there's very little inner alignment if at all).
<pjb>
elderK: so lines that have more than 80 characters, can still be within reasonable width when displayed in a nice proportional font.
<didi>
Proportional fonts? On source code? You, monster.
<pjb>
No, really, try it; on lisp source (or pascal source) it's ok.
<didi>
Eww. Gross.
<beach>
I would love to do that.
<pjb>
For example (frame-font) -> "-*-Bodoni 72-normal-normal-normal-*-17-*-*-*-p-0-iso10646-1"
<makomo>
now i realize my message didn't even get through, ugh...
<makomo>
pjb: re: learning a language: i do that as well. learn the little elements and the means of composition and voila
<makomo>
i don't like learning language features by "pattern matching", i.e. reading examples. reading the whole spec/reference of the thing is always the best
<makomo>
but one thing that requires lots of examples (i.e. reading lots of code) is developing a style and learning the idioms/conventions
<pjb>
makomo: so you've got a goal: there are 678 symbols in the CL package.
orivej has quit [Ping timeout: 268 seconds]
<pjb>
(now, some symbols represent several concepts, such as function type etc, and some concept are not precisely represented by one single symbol, but learning 2 CL symbol a day should let you cover it all in one year).
<pjb>
So, with such a proportional font, you can easily pack twice the characters in the same window width!
nanozz has joined #lisp
<pjb>
Oh, and the mode line is not truncated anymore!
<pjb>
And the comments, fontified in oblique, become BEAUTIFUL!
heisig has quit [Ping timeout: 276 seconds]
<elderK>
pjb: I don't see what the frame-width stuff is for.
<elderK>
I use Vim, not Emacs.
<pjb>
elderK: I assume you have a function in vim to get the width of your frame too?
<elderK>
As for line length, it's actually pretty important to me. I have extremely poor eyesight, text is usually large. 80 characters per line, fits pretty well. But not more than that.
<pjb>
If I used a 8x8 character matrix, I can have 400x222; 222 lines of 400 characters.
<elderK>
Great. That would be too tiny for me to read. Unless I was at an extremely low resolution.
<elderK>
Back when 800x600 was the norm, I used to use the DEC Terminal font. It was nice. Unfortunately, at higher resolutions, that font stops being feasible. It makes me sad. It was a great font.
<pjb>
elderK: use (with-open-file (source "foo.lisp") (let ((*print-right-margin* 72)) (loop for sexp = (read source nil source) until (eq sexp source) do (pprint sexp))))
<pjb>
elderK: there's terminus, or menlo on macOS.
<pjb>
and a few other nice fonts.
kajo has quit [Quit: From my rotting body, flowers shall grow and I am in them and that is eternity. -- E. M.]
<elderK>
I tend to use Monaco these days. Or Raize. Raize is nice.
<pjb>
elderK: put (defun pp-list-source (file) (with-open-file (source file) (let ((*print-right-margin* 72)) (loop for sexp = (read source nil source) until (eq sexp source) do (pprint sexp))))) in your rc file, and use it in the repl to list the sources.
<elderK>
Thank you.
<pjb>
elderK: it's just a Q&D proof of concept of course. You may write better tools to help you.
rjid has left #lisp [#lisp]
<elderK>
I generally try and write code so that I don't /need/ massive lines.
kajo has joined #lisp
<elderK>
I still have a lot to learn in that department regarding formatting of Lisp expressions.
<elderK>
Still, that snippet may come in useful. thank you.
<pjb>
it's that we use long names usually.
<pjb>
long and explicit.
<elderK>
One thing I'd like to know, is how to format long parameter lists. Or, the parameter list of a defun where the function name is pretty long, and the parameters wont fit on the same line.
<elderK>
I've seen some code where it's like (defun some-really-long-name
<elderK>
then the parameter list is 4 indented.
<elderK>
then the body forms, two indented as per usual.
josemanuel has quit [Quit: leaving]
<elderK>
:) I guess in time I'll develop a personal style to make it... sane for me. It's like conventions I follow when writing C, a lot of people hate it. But for me, they're vital for reasons mentioned above.
<pjb>
Really, you can put a newline everywhere a space can be put.
<elderK>
Also, having short lines makes it easy to do code reviews with splits :D
<pjb>
So if the function name is very long, put a newline between it and the lambda-list.
<elderK>
pjb: Aye. That's what I figured, but then you need some way to make the lambda list clear, that it IS the lambda list. Of course, anyone reading Lisp regularly will be able to tell that right away.
<pjb>
If the parameter list is long, you can put a newline between each parameter (and even add a 1-semi-color comment after each paramete).
<pjb>
elderK: it's made clear by the indentation.
<elderK>
pjb: I need to do the indenting mostly by myself. slimv fails here pretty badly.
<pjb>
Well, of course, the advice is to use emacs.
<elderK>
I figure the lambda-list would be four spaces in, rather than the two for a usual body.
<pjb>
Well, indent is not a filter,you'd have to modify the script to make it a filter, which would allow you to re-indent only parts of your buffer.
jack_rabbit has quit [Ping timeout: 252 seconds]
<makomo>
pjb: haha, i like how the script uses emacs :')
dueyfinster has quit [Quit: My iMac has gone to sleep. ZZZzzz…]
<elderK>
How "readable" are Emac's like, indentation... uh... scripts.
<elderK>
Perhaps this is something I can contribute. An improved Lisp-indentation script for Vim :P
<elderK>
Or yeah, just alter your script :D
<elderK>
Or bite the bullet and learn Emacs + EVIL/Viper
<pjb>
They're written in emacs lisp, but you'll have to know emacs, it's particular.
<makomo>
elderK: or switch to emacs ;-)
<elderK>
I've been using Vim for a long, long, long, long time. I'm pretty attached to it.
<makomo>
elderK: i use emacs with full blown vim keybindings
<pjb>
There's some specific generic mechanisms that are not particularly language specific.
<elderK>
makomo: Interesting. Are you a expat Vimmer? :D
<pjb>
So, yes, read them, recover and document the indentation rules as specification, and implement them in vim or even in CL.
<makomo>
elderK: i started off with Vim first and used it for some time. i liked the concept of modal editing very much. then i found out about emacs but couldn't get myself to stick to it because of its non-modal defaults
<elderK>
I mean, the popular editors people use today seem to be stuff like Atom and stuff. And those have SLIME interfaces. Those people will have to manually indent, too, unless their "indenters" are more powerful or featureful out of the box than Vims.
<makomo>
elderK: then i found Spacemacs and that was it :-)
<elderK>
makomo: What made Spacemacs so much better than normal Emacs for you?
<elderK>
I tried to learn Emacs a long time ago. It did not last long :P
<makomo>
Spacemacs is an emacs "configuration pack", i.e. a "ton" of Emacs Lisp that configures a lot of stuff for you out of the box. Spacemacs in particular configures Vim keybindings and "Evilifies" a lot of modes for you
<makomo>
s/in particular/also/
<makomo>
i would say that the vim part of spacemacs is its best feature. it combines the power of modal editing with the power of emacs' extensibility (emacs lisp)
<makomo>
you can switch back to "emacs editing mode" (and back to "vim editing mode") at any time with a keybind
<elderK>
makomo: How about the other... stuff. Like say, sending stuff to the REPL or whatever. Do you find yourself having to use say, "Vi ish" keybinds for actual editing vs. Emacs-ish ones for the rest?
Lycurgus has left #lisp ["Deus Ex"]
<elderK>
Like, maybe it seems dumb but I want to spend my time learning and experimenting with CL, not with Emacs.
<elderK>
makomo: How long until you felt comfortable like?
<makomo>
elderK: that's exactly the problem that Spacemacs tries to solve. not only does it have vim keybinds for editing, but it also tries to configure vim-like keybindings for other "modes" (a mode in Emacs is what a filetype is in Vim, or at least that's the comparison i've heard)
<elderK>
Maybe Emacs is one of those "Dentist-like" things. It's really not so bad. It seems like this huge thing to get used to, but it's probably not so bad.
lumm has quit [Quit: lumm]
<makomo>
sometimes it happens that you'll have to configure a certain mode yourself, i.e. set up the vim-like keybindings for it yourself. but most of the popular stuff Spacemacs already handles for you, so it's very easy
<makomo>
for example, to eval a defun, i just do ", e f"
<elderK>
Nice :)
<makomo>
elderK: i'm not sure how long it took, but assume a few weeks or something (i guess?)
<makomo>
elderK: yeah, it's not that bad, especially with Spacemacs around now. i'm not sure if i would have switched if it wasn't for Spacemacs, heh
nullniverse has joined #lisp
<makomo>
some people say you shouldn't start with Spacemacs as it'll hide the vanilla behavior of Emacs from you and make it harder to understand stuff, etc. while that's true to some degree, i think the benefit of Spacemacs are much larger than that drawback
<makomo>
benefits*
<esper0s>
i have been using emacs for a year now, loving it but oh my god the random buffer popping up is hideous
<elderK>
Thanks makomo. I might give it a shot :)
<esper0s>
and i dont have the time rigth now to dive deep to the api to change te behavior
josemanuel has joined #lisp
<makomo>
elderK: also, the drawback isn't that hard to overcome anyway. it's always the same -- rtfm. :-) read emacs' manual, read spacemacs' manual and see what exactly is the vanilla behavior and what new concepts spacemacs introduced
<makomo>
elderK: i would highly recommend it :-)
ryan_vw has quit [Ping timeout: 245 seconds]
<makomo>
elderK: for example, emacs has the notion of a "package", but spacemacs introduces the notion of a "layer" which is a logical grouping of packages that are meant to be used together or are somehow logically connected
<makomo>
elderK: to install an emacs package you would use emacs' own commands, but to install a layer you would use spacemacs' commands
jochens has joined #lisp
jochens has quit [Ping timeout: 268 seconds]
doubledup has quit [Quit: Leaving]
<elderK>
Wow, spacemacs looks really awesome!
SaganMan has quit [Ping timeout: 252 seconds]
<makomo>
elderK: yay! :D
dueyfinster has joined #lisp
longshi has joined #lisp
<pjb>
elderK: yes, and similarly, don't spend your time customizing vim. Instead, write your own environment and editing tools in Common Lisp. You can use portable Hemlock as basis, or start from scratch.
<jcowan>
and likewise cos and tan; arcsin and arccos return #C(nan, nan), but atan(inf) is, bizarrely, 1.5707963267949.
<jcowan>
(in double precision)
<jcowan>
oh, of course, pi/2.
another-user has quit [Remote host closed the connection]
warweasle has joined #lisp
<esper0s>
thank you for the links the second book about text editors was god send as iam now writtin a text editor
<esper0s>
how lucky am i
<esper0s>
thank you very much
nly has joined #lisp
orivej has joined #lisp
<beach>
esper0s: Do you have some kind of specification for it?
<beach>
esper0s: Or, perhaps you want to give a short description of it?
longshi has quit [Quit: WeeChat 2.3]
<esper0s>
no iam alright with it, i have not started it yet as iam making a library of ansi ascape sequences first
<esper0s>
and generally learning to manipulate the terminal
<esper0s>
it will be a tui text editor
<beach>
So no GUI?
<beach>
I see.
<beach>
Do you already know how to represent the buffer(s)?
<jcowan>
I have concluded reluctantly that my editor (if/when I get to it) will have to have a few ANSI escapes, though I had hoped to make it pure TTY interaction
<jcowan>
I'm trying to hold it down to "up" and "reverse video" on a few characters (to show that they are not literal)
<esper0s>
no i still dont know how to represent the buffer
<beach>
OK.
<esper0s>
have thought of dynammically allocated arrays
<esper0s>
iam using c by the wway not lisp
<beach>
Sorry to hear that.
<esper0s>
lisp is the second language i want to learn but after i become good at c
dueyfinster has quit [Read error: Connection reset by peer]
<pjb>
Is it possible to become good at C?
<jackdaniel>
esper0s: contributing to ECL may be a way to learn both at the same time
<pjb>
good point!
<pjb>
clisp is written in C too.
<pjb>
How to represent buffers is less important than to define a good interface to this abstraction. You can change the implementation later.
<jackdaniel>
esper0s: ecl is one of common lisp implementations
<jackdaniel>
its core runtime is in the C world, so it is easy to interoperate with software knowing how to deal with C ABI both ways
<pjb>
one strong point of ecl is that it has a libecl.so library so you can generate unix executables that are as small as C executables. Also, you can embed it in C applications.
<esper0s>
so basically you can right applications in ecl and run tose applications with a c compiler like gcc?
<jebes>
also of interest is clasp
<jebes>
which is in clang
<jackdaniel>
jebes: wrong, clasp compiles to llvm (it is interesting but it has different qualities which make it interesting)
<jackdaniel>
esper0s: ecl has a compiler which compiles to c and then runs a c compiler on that for you, no need to do it by hand
<jebes>
excuse me, sorry i was confusing llvm with clang
<jackdaniel>
(fwiw it may compile to c++ too)
<jackdaniel>
another interesting feature is that you may have Android applications which utilize ECL (see project eql5-android for examples)
<esper0s>
thank you for the information :)
<jackdaniel>
sure
sabrac has joined #lisp
<elderK>
I imagine being good at programming is less about the language, and more about the concepts and stuff you have to leverage. So, sure, you can be a good C programmer. Of course, as with human languages, the language you speak can influence how you think. So, some things that work really with in C, the C way, obviously do not translate well to say, Lisp. And vice versa.
sabrac has quit [Client Quit]
<elderK>
But learning both, gives you access to more concepts and ways of thinking, which hopefully makes you a better programmer.
* elderK
shrugs
<elderK>
Likewise with other Lisps - what is good Scheme is not necessarily good CL.
<jackdaniel>
having access to more convenient tools may prove fatal if you need to write later in a language which doesn't provide them
<elderK>
True.
<esper0s>
exactly, iam just using c as a medium to become a better programmer, as i like embedded systems and those are mostly implemnted in c, also iam very diasspointed with university, they have been teaching us 7 languages and havent gone deep to any of those
<esper0s>
the language is just the syntax, but learning to represent concepts is the tricky part
<jackdaniel>
university is not for teaching you anything, only to show you directions in which you may teach yourself
<esper0s>
seems like it..sight
<esper0s>
sight
<esper0s>
sigh
<esper0s>
:D
<jackdaniel>
minion: tell esper0s about paip
<minion>
esper0s: paip: Paradigms of Artificial Intelligence Programming
<jackdaniel>
esper0s: paip is freely available recently on github
<jackdaniel>
it has numerous case studies which are both intelligible and teach you a lot
<jackdaniel>
this book is in scheme, but also covers many important subjects in programming and computer science
<esper0s>
yes i got this book
<esper0s>
thank you again :)
<jackdaniel>
studying either of these books will make you certainly a better programmer than you'd become if you had only followed assignments without expanding your knowledge
<esper0s>
iam not following the assignments, iam doing my own projects
<esper0s>
right now diving deep to terminals by doing 3 projects
<jackdaniel>
I've said, that following assignments is not enough, not that it is unnecessary, make no mistake
<esper0s>
a terminal application to practice touch typing, a text editor and a dynamic interface to change the termios driver attributes
<esper0s>
but the amount of information can be exhausting at times
<elderK>
esper0s: A major issue I find is that no matter how much information you may read, how much code you study in a day, there's only so much of it that the brain can reliably digest and get something out of.
<elderK>
It's like AMOP, SICP, PAIP and even CLtL2. I have all of those in hardcopy.
<jackdaniel>
as of embedded systems, as a former embedded systems engineer I can tell you without a doubt that low resource systems are a past
<elderK>
I have read them all. For SICP, I even did the majority of the tasks.
<elderK>
But that was done in a big WHACK! as it were.
<jackdaniel>
it is simply cheaper to build toasters on arm chips than using atmega chips and similar
<elderK>
It's like Math. You can study Math, and do lots of practice. You need to to really nail the concepts. But, unless you periodically refresh it, it's going to decay. You might not forget it entirely - but it will definitely rust.
<jackdaniel>
so usually you have (a limited) Linux on board and any language you can imagine
<jackdaniel>
be it python, C or Common Lisp
<elderK>
Human Brain as DRAM :D
<esper0s>
so you mean to say that the way embedded systems is going the industry might choose to adopt different a different language as a standard?
<makomo>
whew, imagine connecting to your microwave that's running CL using SLIME from emacs :-D
<didi>
jackdaniel: Nice. Low resources are a downer.
Inline has quit [Read error: Connection reset by peer]
<elderK>
I mean, it's giant.
<pjb>
elderK: but only because it uses local functions.
<elderK>
Yup. It's still kind of... intimidating.
<trittweiler>
elderK, look at usage examples, use an interactive macroexpander and annotate pieces of the code with calls to FORMAT to see in what steps the expansion is computed
<elderK>
I mean, I understand that if say, he split the functionality out into separate functions... just to make them smaller, easier to understand in and of themselves, he'd probably have to hand a bunch of extra parameters to stuff. AND make sure that they're around at compile-time / load-time, etc.
<pjb>
elderK: you can use hideshow mode to hide the local function bodies.
<pjb>
elderK: write the same feature in your editor!
<pjb>
elderK: you know, you're not the first one to have those problems. They have been solved! in emacs.
<elderK>
trittweiler: I'll give that a shot.
<elderK>
pjb: I intend to start giving Spacemacs a shot tomorrow, when I wake.
<pjb>
elderK: ok, there's a solution: (defun pp-list-source (file &optional (*print-depth* nil)) (with-open-file (source file) (let ((*print-right-margin* 72)) (loop for sexp = (read source nil source) until (eq sexp source) do (pprint sexp)))))
Inline has joined #lisp
<pjb>
and use (pp-list-source "file.lisp" 6) ; in this case.
<pjb>
but indeed, it'd be better to implement a little function that would allow you to hide or show each subexpression at will.
<elderK>
pp-list-source?
<elderK>
Oh, right.
<pjb>
elderK: yes, slowly, write tools and commands to build up and customize your environment.
<pjb>
elderK: have a look at hemlock in ccl or portable hemlock.
<pjb>
(ql:quickload :hemlock.tty) or (ql:quickload :hemlock.qt)
<pjb>
Beside sedit, I also have an ed(1) clone in CL: com.informatimago.common-lisp.ed.ed:ed
<pjb>
(Missing integration of a regexp package, you could add cl-ppcre for regexps).
aindilis has joined #lisp
SaganMan has quit [Quit: WeeChat 1.6]
nullniverse has quit [Quit: Undertaking stack overflow prevention]
cage_ has quit [Remote host closed the connection]
igemnace has quit [Quit: WeeChat 2.3]
didi has left #lisp ["O bella ciao bella ciao bella ciao, ciao, ciao."]
warweasle has quit [Quit: rcirc on GNU Emacs 24.4.1]
frgo has quit [Read error: No route to host]
frgo has joined #lisp
<elderK>
So, I'm slowly managing to understand it. Just by reading it... Force of will and all that.
<elderK>
It's made harder because it seems that he's used tabs in his source. But, inconsistently.
<elderK>
So, (if ...)s aren't always formatted correctly
<elderK>
I guess the more you read Lisp, the better you get at understanding code like this.
<jackdaniel>
it is true with any language
<jackdaniel>
in a matter of fact, with any pattern
<elderK>
Aye.
<elderK>
I mean, it's nice code and all. The majority of it is pretty nice. Just, iono, it gives me something to think about. Like, now that I'm starting to understand the ins and outs of his define-binary-struct macro, I'm thinking: Could this be written in a way that is clearer or easier to read?
<elderK>
Over the past few months, I've been spending a lot of time reading code. I wouldn't say I've spent more time reading than writing but I've definitely upped the amount of time I spent reading "foreign" code.
<elderK>
And, tbh, it's definitely worth it, in and of itself.
<elderK>
:P I've started telling my tiny group of friends that they should try and read code as much as they write it so that they like... develop a sense of what's hard to read, and what isn't and so on.
<elderK>
I wish I spent more time doing this in the past :)
<elderK>
I /should/ be working on sleep. But, iono, I feel oddly compelled to keep reading. :)
<elderK>
Off topic, is anyone here interested at all in like, "Software Archaeology?"
ski has joined #lisp
dddddd has joined #lisp
razzy has joined #lisp
<Xach>
i am interested only in common lisp
<jebes>
eventually apl even makes sense
<jebes>
i reached that stage recently
<jebes>
I'm now applying to work cobol for the irs
<jebes>
the pain keeps getting worse
skidd0 has joined #lisp
<elderK>
You poor soul
<elderK>
Xach: Fair enough :)
<elderK>
:) I'm hoping that sooner or later, CL will be my primary language :D
<elderK>
That would be so cool.
<elderK>
Ten years late :P Better late than never, I guess.
<jebes>
with the direction the IT industry is going, we just need to rebrand it as something else
<jebes>
maybe kombinator.
<jebes>
same as common lisp, new name.
<jebes>
web people will eat it up.
<jebes>
after all, cs cares not to sit on shoulders of giants, but on the toes of investors
<jackdaniel>
I'm afraid you underapreciate people intelligence
<jebes>
jackdaniel: only san fran devs
<skidd0>
CL.Next();
<skidd0>
that'll pull in the web folk
<elderK>
CL.Next? :P
<elderK>
Not the same as CL21 is it?
kajo has quit [Ping timeout: 252 seconds]
<pjb>
bah java 8 has lambda.
rozenglass has joined #lisp
aeth has quit [Ping timeout: 272 seconds]
<elderK>
Yeah but it sucks.
ggole has quit [Quit: ggole]
<elderK>
I had to mess with Java for Uni. I hated it. God did I hate it.
<jackdaniel>
Java is a decent language. it is not CL, but isn't as bad as people try to shame it
<jcowan>
`"In computer science, we stand on each other's feet."
<jcowan>
I've been working Scala and learning Kotlin
<jackdaniel>
as of name of a common lisp for wide audience, we should call it "Not a Common Lisp" and claim that it has been developed by "The average Joe programmer"
<skidd0>
i'd check that link on HN
<skidd0>
Not so Common Lsip: Construction worker creates better lisp for all
<jcowan>
The R2RS report on Scheme was subtitled "An Uncommon Lisp". A stupid piece of snark IMAO, and I'm glad we dropped it.
<elderK>
Interesting. CLHS says that unless you specify :read-only nil as a defstruct slot option, it's implemention-defined whether or not there'll be a setf expander for it.
<elderK>
Actually, even if you specify :read-only nil it's implementation defined.
<elderK>
Whaaaa? It seems like a contradiction.
<pjb>
LOL Laughing Object Language
<pjb>
PLP Programming Language Premium
<elderK>
I must be misunderstanding.
<pjb>
Lapis Language to Aid Programming Intersting Software.
<makomo>
elderK: you should take a look at the ONCE-ONLY macro for a real brain teaser :-)
<jcowan>
The sentence "When this option is false or unsupplied, it is implementation-dependent whether the ability to write the slot is implemented by a setf function or a setf expander" has a bad ambiguity in it
<elderK>
Early in the description, it states that it creates readers for the slots, and they are setfable
<makomo>
oh wow, that is a giant macro indeed
<elderK>
Then later it says if you don't specify :read-only, or give it a falsey value for :read-only, it's implementation defined whether the slots are setfable.
<elderK>
So, which is it?
<jcowan>
I read it as meaning that an implementation may use a setf function or a setf expander, whereas you are reading it as if it ended in "... or not".
<pjb>
Pacas Programming Advanced Component Added Software. For java users.
<elderK>
jcowan: I don't follow.
<elderK>
I thought like, if you wanted to do (setf (something) value), you had to have a setf expansion?
<pjb>
elderK: setf can work in other ways than with a setf function or a defsetf or setf expander.
<jcowan>
On my reading, it doesn't say that setfability is optional, it says that the means of providing it (function or expander) is up to the implementation. But I agree that it's badly drafted.
<pjb>
elderK: setf can work in implementation dependant ways for structure writers.
<pjb>
elderK: this is a door open to let implementation optimize structures in very special ways.
<pjb>
Some old implementations took advantage of it. Modern implementations tend to define structures as subclasses of clos objects.
<makomo>
elderK: a "setf function" and a "setf expander" are just two ways of providing a "place" for SETF to operate on
<jcowan>
apparently however CLHS demands that one or the other must be used here
qapples has joined #lisp
<makomo>
"places" are also known as "generalized variables"
qapples has left #lisp [#lisp]
<elderK>
Ah, I see.
<elderK>
So, as long as you are able to (setf (struct-slot ...) ...), it's just saying how you manage to provide that ability is open.
<elderK>
Thanks guys.
<elderK>
The way it's worded... was kind of confusing :)
<elderK>
makomo: Took me awhile, btw, but I finally grokked that macro :D
<elderK>
I have now learned that if you create a macro, you really should define the grammar of that somewhere so people can see exactly how it is to be used, just like CLHS does for say, defstruct or defclass. :D
<makomo>
elderK: exactly right
<makomo>
elderK: the binary-types one?
<elderK>
Yeah
<makomo>
mhm
<makomo>
yeah, that's a good idea (regarding the grammar)
<elderK>
It's not really doing anything all that complicated, not really. Just, very... clumped together.
<makomo>
or if the macro is simple enough, a couple of examples with their expansions or something
<elderK>
Yeah, exactly.
<elderK>
And ideally, you'd have all of those figured out before you started writing the macro, anyway.
<makomo>
yup
<elderK>
I get the feeling that the binary-types stuff was intended to support more stuff originally, or in the future, but was never... fully completed.
<elderK>
Or rather, the goalpost changed. It is complete. But there are signs that it was meant to do more.
<elderK>
I find that kind of interesting :)
josemanuel has quit [Quit: leaving]
scymtym has quit [Ping timeout: 276 seconds]
ryan_vw has joined #lisp
robotoad has joined #lisp
<elderK>
Question: If a macro is meant to evaluate one of its arguments, does it have to call eval on it?
<makomo>
elderK: good question. you're referring to evaluating the argument whilst computing the expansion, right?
<makomo>
(instead of arranging for the argument to be evaluated within the generated expansion)
<elderK>
I think so, yes. I'm not entirely 100% sure what I'm asking. I just know that some macros say "The argument is not evaluated" and others say "The argument is evaluated in the environment active at the time the macro was called."
<pjb>
elderK: no it doesn't have to evaluate, but ensure that the argument is evaluated at run-time.
<elderK>
For, for the former, I figure the argument is patched directly into the expansion.
<makomo>
elderK: you're thinking of the latter then. the former would be macroexpansion-time evaluation, which is a rare thing to do
<pjb>
elderK: in general it would be difficult to evaluate something at macroexpansion time, because EVAL doesn't take an environment argument.
<pjb>
elderK: notice that macros can receive an environment argument!
<pjb>
elderK: and macroexpand (and find-class) take one.
<makomo>
oh wow, i wasn't aware FIND-CLASS takes an environment parameter
<makomo>
how come?
<elderK>
Interesting. So, "argument is not evaluated", is that the same as just... splicing it directly into the expansion somehow? Or do you splice in the argument, quoted?
<pjb>
elderK: so the only case where you would "evaluate" something at macroexpansion time, would be when that something would be a macro or symbol-macro and you would 'evaluate" it by macroexpanding it.
<pjb>
makomo: so you can define local classes.
<pjb>
elderK: correct.
<makomo>
pjb: right, but how do you do that?
<pjb>
(defmacro set-double (var expression) "evaluates the expressions and binds the resulting value to the variable var" `(setf ,var ,expression))
<pjb>
(defmacro set-double (var expression) "evaluates the expressions and binds the resulting value times 2 to the variable var" `(setf ,var (* 2 ,expression)))
<elderK>
Okay, and if the argument /is/ evaluated, you mentioned you'd arrange to /have/ it evaluated at the right time. How would you go about doing that? Would you create some gensymed variable somewhere and say, hey, evaluate this at whatever time, and use this gensym when referring to the "argument"?
<makomo>
i think pjb read your first question wrong?
<makomo>
what pjb just described is the case when the arguments /are/ evaluated (by arranging for them to be evaluated within the expansion)
<pjb>
Here, since ,var is in a place position in the setf form, it's not "evaluated" as such (it's evaluated as a place by setf). But since expression is expanded in a position that is evaluated by setf, then set-double has fulfilled its contract.
<makomo>
elderK: to "arrange for something to be evaluated" means to splice it into the proper places within the expansion
<elderK>
Okay, and to have it /not evaluated/ would mean to splice it in, but make sure it's quoted when spliced?
<elderK>
so ',name vs ,name
<elderK>
?
<makomo>
elderK: either that, or to splice it into some place where it won't get evaluated
<pjb>
Basically, standard special operators and macros define what argument is evalauted and when, and what are not. And function calls evalutes all its arguments.
<makomo>
elderK: for example, the LET special operator doesn't evaluate the names
<makomo>
yeah, what pjb said
<pjb>
So macros can use their own parameters in those different ways, by putting them in forms using those special operators and macros or fucntion correspondingly.
<makomo>
elderK: so, in (let ((,name ,value)) ...), name won't get evaluated
<elderK>
Aye, but what's to stop them giving us some (make-symbol ....) thing? In that case, we are relying on LET not evaluating the names, right?
<makomo>
elderK: if they do so, the expansion will be incorrect, as the NAME will be the actual form (MAKE-SYMBOL ...)
<makomo>
so that'll be an error
<elderK>
For argument sake, let's assume LET itself is a macro and expands to something else, maybe a lambda or something, who knows. Then the name would be expanded into a lambda list. And that's where the error would be caught, no?
<elderK>
So, basically, whether or not something is evaluated or not, really depends on 1. We quote it when we create our expansion like ',name. OR it depends on what operators we use with that spliced argument.
<elderK>
Like with expanding to (setf ,var ,expression). ,var will not be evaluated.
<pjb>
(defmacro let ((&rest bindings) &body declarations-and-body) `((lambda ,@(mapcar (lambda (x) (if (listp x) (first x) x)) bindings) ,@declaration-and-body) ,@(mapcar (lambda (x) (if (listp x) (second x) nil))))) ; more or less
<makomo>
elderK: perhaps. what if you pass in an expression that is something like (&optional hi) and the LET macro splices its arguments? you might actually get a valid lambda list :-)
<Bike>
in the same way that if you write (setf foo bar) in code the foo won't be evaluated.
scymtym has joined #lisp
<elderK>
pjb: I appreciate you trying to help but code dumps like that in IRC are not all that helpful.
<White_Flame>
elderK: the way I normally state it is that macros take source code and return source code. If your macro foo is called as (foo a b (bar baz)), it gets the _source code_ forms A, B, (BAR BAZ). Any values associated to those probably don't exist, unless you're very particular in your build to assure some (usually global) values exist at compile-time
<makomo>
elderK: but yes, hopefully the error would be caught somewhere (either in the expansion (at run-time when the code is run) or the macro itself would catch it by doing some analysis)
<pjb>
(defmacro let. ((&rest bindings) &body declarations-and-body) `((lambda ,@(mapcar (lambda (x) (if (listp x) (first x) x)) bindings) ,@declarations-and-body) ,@(mapcar (lambda (x) (if (listp x) (second x) nil)) bindings))) (macroexpand-1 '(let. ((a 1) (b 2)) (+ a b))) #| --> ((lambda a b (+ a b)) 1 2) ; t |#
<makomo>
elderK: in the end, whether or not a macro argument is evaluated depends on the expansion produced. if the expansion evaluates an expression that was bound to a macro argument ARG, we say that the macro evaluates ARG
<pjb>
elderK: Sorry, I don't see the difference between 300 characters of english and 300 characters of lisp.
<elderK>
Okay, I think I understand now. Thank you for answering my question :)
<elderK>
pjb: It's less the code that is the problem, tbh. It's more than in IRC, it's all squished into one or two lines and I'd need to copy it out, format it, so that I could understand it. The more code there is, the more I need to do that.
<elderK>
:) Still early days, you understand.
random-nick has quit [Ping timeout: 272 seconds]
<pjb>
Oh, I see, it's because you don't use emacs.
<makomo>
elderK: but saying that "the macro evaluates ARG" is technically incorrect, as it's not the macro that evaluates it (at macroexpansion time), it's the expansion that it produces
skidd0 has left #lisp ["WeeChat 2.2"]
<makomo>
but evaluating at macroexpansion-time is so rare that we take that sentence to mean the conventional thing that everyone just described
<pjb>
emacs matches the parentheses so you don't have to copy and paste and indent in general. it's enough to move the cursor over the parentheses. emacs shows the structure autoamtically.
<elderK>
pjb: No, I don't use Emacs as my IRC client.
<pjb>
yes, this is the problem.
<pjb>
;-)
<elderK>
:|
<elderK>
makomo: Thank you. And aye, I should be clearer. White_Flame, that's how I see macros too.
<pjb>
elderK: but don't you already have a command that does that automatically? I thought vim was scritable too.
<elderK>
It would be interesting to see how defstruct is implemented.
<White_Flame>
M-. will take you there
<Bike>
it's probably going to be hard to understand, though
<White_Flame>
(as long as you have slime set up to see your implementation's source code)
<elderK>
pjb: Vim handles paren matching, etc, etc. But code in IRC still requires me to copy the stuff out of IRC, into Vim, then I have to do whatever to format it.
<makomo>
elderK: if you want to document that something actually gets evaluated at macroexpansion-time, then you would say "evaluates ARG at macroexpansion-time" (instead of just "evaluates ARG")
<pjb>
elderK: see for example: com.informatimago.common-lisp.cesarum.utility:define-structure-class
<elderK>
God damn that's a huge name.
<elderK>
:P
<elderK>
What is your nickname for that? :P
<pjb>
It takes the same argument as defstruct, but expands to a defclass.
<pjb>
define-structure-class.
<makomo>
pjb: that's neat
<elderK>
No, I mean the package.
<pjb>
I use my packages.
<elderK>
Yes, of course. But I mean, you have to (:use ...) that package.
<elderK>
Do you literally type that huge name? Or do you have a nickname for it?
<elderK>
Okay. So, to answer my question: No, I don't use package nicknames fo rit.
<elderK>
:P
<pjb>
elderK: Since most of my code is written in libraries, it cannot use package nicknames.
<elderK>
Fair enough
<pjb>
only the end user can define package nicknames.
<pjb>
short ones I mean.
<elderK>
Makes sense.
<elderK>
I've seen a few issues around where package nicknames collided.
<elderK>
binary-type's bt with bordeaux-threads bt
<elderK>
For instance
<pjb>
LOL
<pjb>
post an issue in both.
<elderK>
They're already aware of it :)
<elderK>
At least it's in the github issue list for binary-types
<equwal>
morning
<elderK>
I kind of want to reimplement binary-types as a learning exercise. I'd like to see if I can do it cleaner.
<elderK>
Particularly those complex macros.
<equwal>
Does fare-quasiquote work in sbcl?
<elderK>
Which raises another question: Macro expansion is recursive, right? Like, if a macro's expansion has another macro in it, that macro will be expanded and do on until it's entirely expanded?
<jcowan>
Yes
<elderK>
Moin equwal
<equwal>
elderK: Yes, but don't try to call a macro from with itself.
<jcowan>
Specifically, when a form is being macroexpanded, it is examined for the outermost macro(s) and they are expanded and plugged back into the form. This repeats until no more macroexpansion can be done.
<pjb>
equwal: of course you can do that!
<elderK>
It seems like it might be useful to have helper-macros then. Smaller macros that help implement the larger ones. Maybe that would have helped make define-binary-struct more understandable.
<elderK>
Awesome. Thanks jcowan.
<elderK>
pjb: As long as you have a terminating case, right? :P
<pjb>
yes.
<elderK>
So, is there anything wrong with using macros as a way to conveniently destructure stuff?
<elderK>
Like, forms I mean, not lists of arbitrary data
<pjb>
And helper macros can be global macros, or local macros with macrolet
<equwal>
Oh you can do that!
<pjb>
macros are just functions like any other function.
<elderK>
Right. Just evaluated at a special time, right?
<pjb>
or (macroexpand-1 '(my-macro …) environment)
<elderK>
Are those two things equivalent?
<pjb>
yes.
<elderK>
Thought so. Awesome :)
<pjb>
more or less. macroexpand-1 will also use *macroexpand-hook*.
<elderK>
And I figure that allows you add new macro-expansioney-support?
<pjb>
Yes, all kind of hacks.
<elderK>
Cool :)
<pjb>
quicklisp uses it to log the packages that are loaded and display the dots when compiling, I believe.
lvmbdv has quit [Quit: WeeChat 1.5]
<elderK>
binary-types goes through a lot of effort to like, destructure it's input in a lot of ways. Is there anything against defining a macro to do that for you?
<pjb>
of course not.
<elderK>
Probably best to write it as a normal function though, right? Maybe local to the macro itself.
<elderK>
Cool :)
<pjb>
indeed.
<pjb>
again, macros are functions like other functions, So you can refactorize them as you wish and would do for other functions.
<pjb>
There's no reason to have big macros as you saw earlier.
<elderK>
I guess this does raise an interesting question though, at least for me: How do you ensure that a macro, which has a ton of local functions, is understandable? Do you just ensure they are all small? Is there some conventional way to format it such that things are better... delineated?
<pjb>
And if you re-read my example substituting backquote with list and other abstract functions I gave yesterday, it more readable.
<elderK>
pjb: Aye, I wondered why he didn't use ` more.
<elderK>
I would have broken the expansion process into a lot of little helper functions, that would be available at compile-time.
<pjb>
Yes.
rozenglass has quit [Read error: Connection reset by peer]
<elderK>
Just, still getting a feel for what's good / bad / normal :)
<pjb>
standard good software engineering practices.
<equwal>
elderK: are you doing that to avoid having nested backquotes?
<elderK>
equwal: Doing what?
<equwal>
Using helper functions.
<elderK>
No. I do it because it makes things easier to deal with, for me at least.
<elderK>
It's a lot easier for me to deal with lots of small functions, than one giant overnested one.
<equwal>
ok
<elderK>
Although, there must be a way to format the code such that a bunch of local functions bound with flet, are jsut as understandable as a bunch of functions made with defun.
<elderK>
Another issue is just, line length.
<pjb>
yes, just insert an empty line between each function and before the body of the macro.
<elderK>
The deeper you are nested when you define your functions, the less space you have per line for the body of a function.
<elderK>
Cool :)
<equwal>
you could use Let Over Lambda's alet/alambda/dlambda combos.
<elderK>
So, just because things are all in a list, doesn't mean they have to be rammed up together, you can insert whitespace and stuff where you please, if it helps. Cool :)
<equwal>
That way your code gets longer instead of wider (on the screen).
<elderK>
equwal: Longer vs Wider? :) I don't own the LoL book yet, I am unfamiliar with those macros.
<equwal>
I just mean if you want to have locally bound functions without using let-like forms you can use anaphors. https://letoverlambda.com/index.cl/toc
<makomo>
i ordered LoL just the other day -- the first book i ever ordered for myself :-)
<equwal>
I like it.
<pjb>
scheme modules are one long sexp from begin to end of the file!
aeth has joined #lisp
<equwal>
lol
<makomo>
equwal: yeah, same. i read it already, but i wanted to have a deadtree copy as well :-D
nanozz has quit [Ping timeout: 245 seconds]
NoNumber has joined #lisp
<equwal>
makomo: I used to have paper copies of a bunch of books, but once I read them I found it is easier to have the HTML files stored locally from httrack.
<makomo>
say i have a "context macro" (i.e. WITH-SOMETHING) but it doesn't really take any arguments except for the body. should i still have an empty list as its 2nd argument just because of convention or not?
<makomo>
so, (with-something () ...) vs. (with-something ...)?
<NoNumber>
What's the channel for lisp noobs to use? IIRC #clnoobs is overrun with spam?
<makomo>
NoNumber: #clschool
<NoNumber>
Thanks
<makomo>
equwal: i also read all of my books in digital form most of the time, but this one i wanted to have irl :-)
<makomo>
i'm also thinking of ordering AMOP
<equwal>
I like to minimize parentheses even when it breaks convention. Anyone with slime can see the arglist in the minibuffer anyway, why not use it?
<equwal>
Personally I think COND is a bit of a mistake with the (cond (predicate result)) syntax. (cond predicate result) would have been better I think, for example.
<pjb>
equwal: nope.
<jackdaniel>
what about body which has more than one form? progn?
<equwal>
Is that implicit progn really worth it? I've never needed it.
<pjb>
also, there's no difference in memory and processing time between an a-list and a p-list.
<makomo>
i.e. has anyone implemented it (and is it even possible)?
<pjb>
makomo: of course.
<elderK>
equwal: I find electronic books to be a lot better than deadtree these days, mostly because of the ability to zoom :)
<elderK>
Although I will say I am oddly proud that I own a copy of CLtL2.
<jackdaniel>
makomo: read-macrolet would need to start with a reader macro itself
<elderK>
I also got the dpANS CL spec printed once in a fit of excitement.
<elderK>
:p
<jackdaniel>
otherwise it is too late to use it
<makomo>
jackdaniel: right, that's just what i thought of. that's a bit ugly :^(
<elderK>
Out of curiosity, can you have macros that expand to macro definitions?
<pjb>
You can even define a macro (cond. test1 => a b c test2 => d e test3 => f g h else i j)
<jackdaniel>
you may want to look for dwim's #feature-case
<makomo>
elderK: of course :-)
<pjb>
anything you can write a parser for.
<elderK>
Wow, turtles all the way down :)
<pjb>
see LOOP for example.
<equwal>
Well that is a place where I don't want a print copy. The locally stored hyperspec with slime is the best way to look at code docs I've ever used.
<makomo>
elderK: DEFMACRO is "just another macro", nothing too special about it
<elderK>
:D Love it.
<elderK>
Although I'm starting to get this whole "Realities of realities" feel
<elderK>
:P
<jackdaniel>
equwal: I'm sure you'd like Allegro CL's if* operator
<pjb>
nope. It's horrible.
<pjb>
I've got an emacs command to replace it with normal if.
<makomo>
what's the IF* operator?
<equwal>
Having trouble finding it in the docs. Link/description?
<makomo>
same ^
<jackdaniel>
I'm talking about his personal aesthetics, not yours, so you can't informely say nope (unless you are the same person)
<pjb>
(if* condition else something then something)
<equwal>
eeew
<equwal>
no
<makomo>
haha
<jackdaniel>
no then, rather (if condition body elif condition body else body)
<pjb>
or (if* condition then something else) if you prefer. or (if* condition else something) for unless
<pjb>
an horror.
random-nick has joined #lisp
<makomo>
and putting ELSE before the THEN is valid?
<equwal>
I think an example that supports my case is where you have a macro that calls another macro for every argument. Like if you have a unit test macro (deftest code result) you might have (deftests code1 result code2 result...) instead of (deftests (code1 result) (code2 result)).
<NoNumber>
Did anyone here start with Common Lisp as their first language? Curious.
<pjb>
yes.
<equwal>
Mine we VB.NET
<pjb>
Perhaps not usual, but possible.
astalla has joined #lisp
<makomo>
pjb: what about when you throw in ELIF into the mix?
<pjb>
NoNumber: Blessed who learns programming with Common Lisp as first language!
<pjb>
makomo: you're right, it might be possible too.
<equwal>
I think scheme might be a better first language though.
<NoNumber>
Well, I've been learning CL as my first language.
<makomo>
i mean, what are the semantics of ELSE ... THEN ... ELIF ... even
<equwal>
No need for the industrial clutter as a beginner.
<NoNumber>
Just wondering if others have done the same.
<pjb>
Now, notice that in CL you can do the same with LOOP
ryan_vw has quit [Ping timeout: 252 seconds]
<pjb>
(loop repeat 1 if (= a 1) then do (something) else do (something-else))
<equwal>
That is horrific haha.
<NoNumber>
Is PCL still a recommended text here in #lisp? Want to make sure I'm not wasting my time going through it.
<pjb>
and of course, with embedded ifs: (loop repeat 1 if (= a 1) then if (= b 1) do (something) else do (something-else) end else do (something-a/=1))
<equwal>
I read it, recommend.
aeth has quit [Ping timeout: 260 seconds]
fikka has quit [Ping timeout: 276 seconds]
pierpal has quit [Remote host closed the connection]
fraxamo has joined #lisp
<equwal>
Just one small step to if* (defmacro garbage (&body body) `(loop repeat 1 ,@body))
<equwal>
(garbage if ...)
<pjb>
:-)
aeth has joined #lisp
hiroaki has quit [Ping timeout: 252 seconds]
<elderK>
:) I like Scheme. ISLISP looked kind of nice, too.
<elderK>
But it has next to no real implementations around.
<elderK>
The standardization of CL is the main reason I chose it, though.
<elderK>
I spent a lot of time playing in Scheme. Lovely language. Great implementations with fantastic communities.
<elderK>
I wonder how many implementations fully support R7RS.
<equwal>
I've never even seen those letters in that order.
<pjb>
RRRRRRRRS
fikka has joined #lisp
<elderK>
equwal: How about R6RS? The last truly widespread revision seems to be R5RS.
<elderK>
That's the revision I learned, anyway.
<pjb>
The revised revised revised revised revised revised revised report on scheme.
<equwal>
I've only seen R5RS
<pjb>
r6rs wasn't pretty.
<elderK>
You might want to look at R7RS :)
<elderK>
It aims to make Scheme a lot more "practical."
<pjb>
there are a few implementations, but people kept using r5rs until r7rs finalized.
<elderK>
And to do some unification.
<NoNumber>
If you want a practical Lisp, shouldn't you just use CL?
<elderK>
AFAIK, R7 finalized a few years ago, no?
<elderK>
Or is it still underway?
<elderK>
NoNumber: That's my thinking.
<equwal>
I don't know if I want that. I like scheme because it is a good simple, small language.
<elderK>
Although I did really, really like the consistency and purity of Scheme.
<elderK>
Silly subjective reasons, too. Like, I like define :) and the way predicates and things are denoted.
<elderK>
I prefer something? to somethingp or something-p
angavrilov has quit [Remote host closed the connection]
<equwal>
If you go back and look at the history you see that CL got stuck with bad design decisions in order to support old code. Great example is the separate namespaces.
<elderK>
I *like* the separate namespaces.
<elderK>
IMO, that was a good idea.
<elderK>
How many times have you seen people contort the word "list" in an arglist just because they'd shadow the "list" function in Scheme code?
<elderK>
ls lis lst etc
<equwal>
They do it in CL too just to save a letter though.
<elderK>
Not that I've seen so far :) But sure, some will.
<equwal>
Paul Graham does it.
<elderK>
Granted though, having to say (funcall whatever args) to call a #'... is annoying.
<elderK>
But not fatal :)
<elderK>
I also missed named let, too. Although I'm sure you could add it with macros :)
<equwal>
That is my primary complaint. Higher order functions are made confusing.
<equwal>
Slightly out of order but reduces the number of parentheses by 1.
<equwal>
like (y (a b) (10 0) (if (= 0 a) b (f (- a 1) (progn (print b) (+ b 1 )))))
<equwal>
Since we are here, what do you guys think about ARC?
<pjb>
I don't see any problem in defining your own dsl, as long as you implement it on CL.
<pjb>
same with clojure, etc.
NoNumber has left #lisp ["Gone."]
shifty has joined #lisp
<aeth>
CL has some concise/odd/unusual names accidentally because they're old and legacy names and CL is mostly compatible with those old versions. Some of these, like defun or mapcar or dolist seem fairly common. Others, like set or get or rplaca, are basically never used.
<aeth>
Both Arc and Clojure decided concise names were great and that everyone should save 3 keystrokes.
<pjb>
anymore.
<pjb>
actually, you may be saving more keystrokes with the longer names, and emacs completion than with the short names, that are more ambiguous.
<aeth>
If you write "dofoo" instead of "do-foo" even though "dolist" exists, I don't like your code. Always hyphenate. And please don't abbreviate. Pretty much the only exceptions I can think of are (1) an accepted abbreviation like "id" that seems more right than the correct full form and (2) something like aref or + that's clearly designed to have potentially many on one line
<pjb>
aeth: nope. it depends if foo is an abbreviation or not.
<pjb>
do-foobar or dofoo.
<aeth>
absolutely not
<aeth>
Write assuming your tools are tools, and not strong AI
<elderK>
aeth: I agree with you
<pjb>
defvar define-condition
hiroaki has joined #lisp
<elderK>
:P Inconsistency.
<aeth>
Emacs will glaldy recognize do-foo as a new form of iteration and highlight it purple. It will *not* do so for dofoo. Are you going to make your users install a gigantic, messy .emacs file?
<equwal>
I think an immense line like (multiple-value-bind (the-first-thing the-second-thing) (long-names this-line-is-very-long)) is just hard to read. If you abbreviate you get a nice (mvbind (fn arg) (...))
<aeth>
There are edge cases where indentation simply won't work, but any random do-foo in particular should pretty much work for everyone, highlighting *and* indentation.
anamorphic has joined #lisp
<aeth>
pjb: If Common Lisp were written from scratch using Common Lisp's newer naming standards and no backwards compatibility in names, it would be define-variable, not defvar. And it wouldn't matter because you shouldn't be using it often enough for it to matter, anyway.
<pjb>
:-)
<aeth>
Don't use old names as an example of what to do. That's how you get Clojure creating *new* ugly names in the 2000s
<pjb>
old names were short because 6 characters stood in a word (36-bit words, 6-bit per character).
<equwal>
aeth: But not doing it gets you PHP.
<pjb>
with a null terminating byte: creat
<pjb>
(6-bit byte).
<aeth>
Now, "defun" might be the one reasonable exception to "define-foo". Maybe "defmacro" and "defmethod" as well because they're the basic building blocks of your program. Honestly? define-class would make more sense. It's not like defclass is even built with conciseness in mind.
<pjb>
aeth: in LeLisp, it was de
<pjb>
or perhaps it was in vlisp, I don't remember.
<aeth>
Although, really... I don't really have an issue with using define-function all over my code, though. I thought I might, but I don't. Turns out that when I'm adding functions, the extra second to type out 'define-function' doesn't really slow me down.
<anamorphic>
Hi, I'm a bit stumped with this expression from the defsetf docs at http://clhs.lisp.se/Body/m_defset.htm (defun xy (&key ((x x) 0) ((y y) 0)) (aref *xy* x y)) - I'm not sure what that keyword arg syntax does
<aeth>
I use 100 character lines so it doesn't give me much of a longer lambda list, either.
rozenglass has joined #lisp
<jackdaniel>
(setf (foo :x 0 :y 15) 43)
<pjb>
anamorphic: it tells that instead of using :x you shall use x: (xy 'x 4 'y 2)
Roy_Fokker has quit [Read error: Connection reset by peer]
<jackdaniel>
ah, that's what he was asking about, nvm me
<pjb>
You may do that when you don't want to export the key argument.
neosloth has joined #lisp
<aeth>
setf, now that's a justified abbreviation.
<pjb>
:=
<pjb>
(:= a 24)
<aeth>
setf/aref.
<pjb>
(:+= a 3) for (incf a 3)
<pjb>
:-)
<aeth>
pjb: If it wasn't a keyword.
<anamorphic>
Thanks pjb
<aeth>
pjb: Although because := is a keyword you can pretend you're writing Pascal in LOOP.
Mr-Potter has joined #lisp
pierpal has joined #lisp
<anamorphic>
Is there some reason in that example code for defsetf that they need to not export a keyword?
<pjb>
No. it's purely incidental. Perhaps they hadn't completed the specification of &key yet when the wrote the example.
<pjb>
Or perhaps the person who wrote the example was the promotor of being able to use normal symbols for &key arguments in addition to keywords.
<makomo>
elderK: regarding the named let, Let Over Lambda does exactly that :-) (implement it as a macro)
<equwal>
Won't work on SBCL though.
dale has joined #lisp
<elderK>
makomo: I imagine you could synthesize named-let with clever use of block or tagbody or something
<elderK>
Still, you'd need to have a new name for let, right? named-let :P
<makomo>
equwal: yeah, sadly. damn backquote :^(
<makomo>
elderK: yeah, i think he calls it NLET or something
<makomo>
but as soon as i saw LoL, i had to read it. at that time i was very interested in macros and i wanted to see everything you could do with them
<makomo>
i just had to explore it
<makomo>
especially when the book was so opinionated and all
<makomo>
it was a real treat :_)
<makomo>
:-)*
<elderK>
makomo: My first was CLtL2 :)
<elderK>
I've been referring to PCL a lot of late, as a companion to CLHS.
<elderK>
Basically, whenever CLHS is too much, I read PCL first, then go back to CLHS.
<makomo>
ONCE-ONLY is indeed a nice exercise, but yeah, you'll want to first start by defining the problem it's designed to solve
<elderK>
makomo: Was my statement of what it's meant to do correct?
<makomo>
equwal: yeah, i've read On Lisp since then as well
<makomo>
elderK: yeah, it was
<equwal>
oh ok
<makomo>
elderK: taking the "evaluates ARG" meaning from before, of course
<makomo>
i.e. the expansion does the evaluation
<makomo>
(no macroexpansion-time evaluations are happening)
<elderK>
:) Sweet.
<makomo>
elderK: to spice it up -- ONCE-ONLY is a macro that writes parts of other macros, i.e. it writes part of another macro's *expander* (the macro itself, the code which produces the expansion)
<elderK>
Create some gensyms, bind them to the result of evaluating whatever. Then rebind those names to the gensym'd ones. Have the rest of the expansion happen inside the form that creatse those bindings?
<makomo>
elderK: i guess that's correct, but it's a bit hard to describe in English without explicit reference to the various macroexpansion "levels"
<makomo>
so it might not be 100% correct, depending on the precise meaning you had in mind :-)
<makomo>
note that there are 2 tiers of gensyms
<makomo>
as ONCE-ONLY has to (1) be hygienic itself and (2) produce expanders which are hygienic
<elderK>
Sounds like a fun exerize
<makomo>
yeah, it's great imo
<elderK>
Aw, I have to make an emacs port first.
<elderK>
:(
<elderK>
Aw
<makomo>
there are 2 things to learn, (1) the conceptual problem that ONCE-ONLY is designed to solve and (2) the backquote hackery that ONCE-ONLY relies on
<makomo>
LoL also implements ONCE-ONLY but in a much easier and neater, but sadly unportable way (nested backquotes are neat in their own way though :-))
anamorphic has quit [Ping timeout: 244 seconds]
vlatkoB has quit [Read error: Connection reset by peer]
<elderK>
Could you clarify what once-only seeks to solve?
<pjb>
evaluate an argument of a macro only once.
<equwal>
I wonder how to understand triple or more backquotes. Like how can I understand what ``````(,@,,@,,,@thing) would do?
<pjb>
elderK: for example, let's write a macro that takes one argument x and builds a list where x is present twice: (list x x)
<pjb>
if you naively write: (defmacro double (x) `(list ,x ,x))
<makomo>
elderK: exactly as you said -- make sure that a macro argument is evaluated only once, but without doing it manually. usually you would (1) create a gensym, (2) bind the gensym within the expansion to the result of evaluating your ARG and (3) use the gensym instead of ARG everywhere within the expansion
<elderK>
I get it.
<elderK>
Back, btw. Got a coffee :)
<elderK>
I see why you'd need two levels.
<pjb>
So you must introduce a temp variable: (defmacro double (x) (let ((vx (gensym))) `(let ((,vx ,x)) (list ,vx ,vx)))) (let ((x 41)) (double (incf x))) #| --> (42 42) |#
<makomo>
elderK: ONCE-ONLY automates that, for an arbitrary number of symbols (known at compile-time)
<pjb>
once-only does this automatically, and use the same name for the temp variable, so you don't have to substitute it.
<equwal>
elderK: You don't have to announce every exit you make from an IRC. Most people come and go, and go long periods without answering.
<pjb>
Now, personnaly, I've never used once-only, On the rare enough occasions, I use gensym explicitely…
<equwal>
pjb: I just did that today
<makomo>
equwal: that's a good question. i have a writeup within my own notes somewhere which i've been meaning to publish if i ever get a blog or something
<equwal>
I'd read it. I can post it if you want.
<makomo>
equwal: but the basic principle is the "ladder algorithm". the number of quotes indicates the number of times an expression will get evaluated (iteratively)
<elderK>
equwal: Okay.
<equwal>
(defun interpol (obj lst) (shuffle lst (loop for #1=#.(gensym) in (cdr lst) collect obj)))
<equwal>
Uses Graham's shuffle
<makomo>
equwal: which of course assumes multiple (iterative) evaluations of the nested backquote form
<elderK>
makomo: I think you just touched on something I was meaning to ask: What's the deal with multiple levels of quoting and unquoting?
<elderK>
`(`(,,a)) say
<equwal>
Basically I don't want to (length lst) when I could just throw things away with a readtime gensym.
<makomo>
` is a *reader macro* that reads in as some implementation-defined form that when evaluated produces a list according to a template
<makomo>
so evaling that you would get (`(,<value-of-a>))
<equwal>
elderK: For double backquote the best way to to learn the "clichés"
<makomo>
equwal: my notes aren't ready yet, i still have to complete some stuff
<elderK>
:) Cliches?
<makomo>
"idioms"
<makomo>
,,@ might look weird at first, but once you get what it does, it's easy
<makomo>
same goes for ,', -- ,@,@ -- ,@, -- ,@', etc.
<makomo>
when using N nested backquotes it is expected that you will iteratively eval the form N times. to iteratively eval N times means to do (eval (eval ... (eval form)))
<makomo>
elderK: the leftmost comma corresponds to the innermost backquote
<makomo>
elderK: which means that the rightmost comma is the evaluation that'll be performed as part of evaluating the outermost backquote
ravndal has quit [Quit: WeeChat 2.3]
<makomo>
so the ,',a idiom is basically "give me the result of evaluating A once, as part of the first evaluation"
<elderK>
Here's hoping that PDF will teach me what I need to know to grok this :)
Guest24308 has quit [Ping timeout: 252 seconds]
<equwal>
The easiest one is ,',X
<makomo>
err, "after 2 evaluations, give me the result of evaluating A as part of the first evaluation"
<makomo>
(eval ``,',a) => `,'<value-of-a>
<makomo>
(eval `,'<value-of-a>) => <value-of-a>
ravndal has joined #lisp
<equwal>
yalp
<makomo>
the quote in there makes the leftmost comma act as a no-op, which is the point of the idiom
<makomo>
i.e. "eval once and hold"
<elderK>
makomo: Other than the linked PDF, are there any other sources of information on this particular topic that helped you understand multiple-level quotes and stuff?
<equwal>
The macro writing books we've been discussing.