freenode/lisp - IRC Chatlog
Search
10:44:13
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.
10:44:37
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.
10:45:19
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.
10:45:32
elderK
So, really, people who gets pissed about this are simply pissed because their favorite shortcut doesn't work
10:46:11
elderK
shka_: Which? There seem to be several :) fast-io by rpav, etc. Awesome as it is, it doesn't do what I want.
10:48:39
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.
10:49:34
elderK
Right. I imagine that allows you to say, have a vector acting as a backing for some stream.
10:50:29
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.
10:50:32
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.
10:51:32
pjb
Well I read the book C Traps and Pitfalls early in my C programmer carreer… https://www.amazon.com/C-Traps-Pitfalls-Andrew-Koenig/dp/0201179288
10:52:20
pjb
ie. you can (list (read-byte s) (read-char s) (read-byte s) (read-line s) (read-sequence byte-vector))
10:54:08
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.
11:00:21
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
11:09:34
no-defun-allowed
Are there any resources on extending swank/slime? I have an idea for a somewhat more useful &body autodoc.
11:10:46
jackdaniel
source code is the most faithful resource in this case, check out contribs directory
11:11:11
jackdaniel
swank is common lisp part with interfaces defined separately and implementations defined per-lisp implementation
11:12:15
jackdaniel
and it is hosted in a separate directory named swank. slime is of course elisp, many things are well commented (but not all)
11:13:06
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.
11:14:05
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.
11:14:36
no-defun-allowed
*that will be derived from a list made by myself, introspection would be a pita.
11:38:56
beach
Otherwise, the method would have to be invoked in order to determine whether it can be invoked.
11:40:35
jmercouris
maybe after this release, which is looking to be quite close now, the MacOS port is almost done, as is the GTK one
11:41:01
jmercouris
just working on changing the Lisp core to handle everything being asynchronous now between the UI and the rest
11:43:16
elderK
:P I have something I want to show you guys, for feedback but I'm kinda scared :P lol
11:43:45
jmercouris
elderK: any feedback you get is an opportunity for growth, not a challenge against your ego
11:44:40
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.
11:45:12
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.
11:45:26
elderK
I saw that there were several such utility libraries around. But, I wanted to make my own, for learning :D
11:45:38
elderK
Anywho, I pushed it here: https://bitbucket.org/elderK/k.utilities.binary/src/default/
11:46:59
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.
11:47:58
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.
11:48:27
elderK
He's not yet at the stage where he could dive into the Linux kernel and really get anything out of it.
11:48:45
knobo1
Funny that I don't know how to make a string with some content, that is not a literal with just one function.
11:49:50
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))
11:51:55
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 :)
11:52:50
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
11:52:57
pjb
(princ-to-string '(1 "hello" hello)) #| --> "(1 hello hello)" |# (prin1-to-string '(1 "hello" hello)) #| --> "(1 \"hello\" hello)" |#
11:53:28
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
11:53:34
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.
11:53:52
elderK
Many students don't even see the point in learning about say, red-black trees or hash tables :(
11:54:13
jmercouris
I'm not sure where you went to school, but our experiences have been quite different, to say the least
11:54:30
jmercouris
not only do they teach everything you've talked about at my school, they teach it in racket
11:54:40
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.
11:54:55
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.
11:54:59
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
11:56:25
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
11:56:42
jmercouris
elderK: perhaps the stuff you are interested in is simply not broadly interesting
11:57:21
jmercouris
and the ones who do it for money "carreer driven developers" don't end up going anywhere anyway
11:57:39
jackdaniel
so in the end we go below physics and we have a computer simulation written in CL
11:58:48
jackdaniel
the rule of thumb is that you pick your level of abstraction and you peak one level below, you are not interested in anything beneath
12:27:04
elderK
Anywho, where is the best place to ask for like, review, I guess. To make sure I'm not doing anything outrageously shit
12:34:09
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 :)
12:37:16
jackdaniel
for starters putting some kind of README at toplevel is expected, so one could get a grasp what the project is all about
12:38:13
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
12:39:07
jackdaniel
you are inconsistent in packages.lisp, you have (:use :cl #:k.utilities.binary), make everything #:foo, like (:use #:cl #:k.utilities.binary)
12:40:29
beach
The FORM of DESTRUCTURING-BIND should be indented 4 positions compared to the DESTRUCTURING-BIND form itself.
12:40:33
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
12:43:19
elderK
Okay? Well, thank you for taking a look. I have fixed the destructuring-bind and comments.
12:44:02
jackdaniel
if this is for learning, then ignore this comment, but did you have a look at a library "binary-types"?
12:45:36
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.
13:02:20
elderK
Thanks for taking a look guys :) I will study binary-types for awhile now. It looks very nice
13:09:05
elderK
jackdaniel: Do you have any advice on how to learn CL, well, more effectively? How did you start off?
13:14:00
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.
13:14:52
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.
13:16:25
elderK
pjb: Other than experimenting and reading other people's work, I'm not sure how to ensure that that I improve.
13:17:56
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.
13:21:48
elderK
hypnon: :) Aye. I guess that is also what makes it a little overwhelming to start off with.
13:25:20
jackdaniel
thanks to that I've made a fair deal: professional guidance of smart people for my time
13:27:57
jackdaniel
in fact I'm still following this patter of learning (reading good resources like books is also helpful)
13:30:19
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?
13:32:04
pjb
elderK: have a look at Mezzano (lisp OS) or at the next browser. or at beach's list: http://metamodular.com/Common-Lisp/suggested-projects.html
13:32:19
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)
13:32:45
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."
13:33:33
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.
13:33:52
jackdaniel
also going through the issue list of biggish projects used by community is a good place for look
13:35:15
jackdaniel
revert some commits to use semaphores from bordeaux-threads (which were recently added there)
13:36:58
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. :)
13:49:21
jackdaniel
didi: sb-ext:double-float-positive-infinity ; other implementations usually have equivalents
13:50:41
didi
jackdaniel: Nice. I wonder if it's possible to write some kind of trivial library for infinity.
13:57:12
scymtym
elderK: for working with vectors of octets, you may find https://github.com/sharplispers/nibbles and https://github.com/scymtym/utilities.binary-dump interesting (if you haven't found them already)
13:58:40
pjb
elderK: or: com.informatimago.common-lisp.cesarum.ascii or com.informatimago.common-lisp.data-encoding.data-encoding etc.
13:59:44
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?
14:02:29
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.
14:04:22
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).
14:12:17
pjb
for cl:short-float : Intel's new Bfloat16 floating-point format: 8 bit exponent, 7 bit mantissa [pdf] <https://software.intel.com/sites/default/files/managed/40/8b/bf16-hardware-numerics-definition-white-paper.pdf>
14:13:01
pjb
oops! nope. short-float must have at least 13 bits of mantissa, and can go down 5 bits exponents.
14:17:26
Bike
sine is a periodic function with a rank of [-1, 1]. it would be pretty weird if sin(inf) = inf.
14:22:33
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.
14:25:38
elderK
Reading "binary-type" right now. Nice code. But the defmacro part for define-binary-record and stuff is pretty crazy
14:26:05
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.
14:26:21
pjb
Bike: for complex, just revert to the fundamental formula: 1+e^ip=0, therefore sin(x)=(e^ip-e^-ip)/2i
14:27:14
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…
14:31:20
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).
14:31:50
pjb
elderK: so lines that have more than 80 characters, can still be within reasonable width when displayed in a nice proportional font.
14:33:35
pjb
For example (frame-font) -> "-*-Bodoni 72-normal-normal-normal-*-17-*-*-*-p-0-iso10646-1"
14:34:01
makomo
pjb: re: learning a language: i do that as well. learn the little elements and the means of composition and voila
14:34:06
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
14:34:28
makomo
but one thing that requires lots of examples (i.e. reading lots of code) is developing a style and learning the idioms/conventions
14:35:26
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).
14:35:53
pjb
So, with such a proportional font, you can easily pack twice the characters in the same window width!
14:42:02
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.
14:43:51
elderK
Great. That would be too tiny for me to read. Unless I was at an extremely low resolution.
14:44:30
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.
14:44:39
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))))
14:46:32
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.
14:47:36
pjb
elderK: it's just a Q&D proof of concept of course. You may write better tools to help you.
14:48:13
elderK
I still have a lot to learn in that department regarding formatting of Lisp expressions.
14:49:27
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.
14:51:06
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.
14:52:05
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.
14:52:07
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).
14:53:20
elderK
I figure the lambda-list would be four spaces in, rather than the two for a usual body.
14:54:35
pjb
or keep using vi, and use 1,$|indent with: https://github.com/informatimago/bin/blob/master/indent
14:56:20
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.
14:58:16
elderK
Perhaps this is something I can contribute. An improved Lisp-indentation script for Vim :P
15:00:02
pjb
So, yes, read them, recover and document the indentation rules as specification, and implement them in vim or even in CL.
15:00:31
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
15:00:35
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.
15:01:36
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
15:02:26
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)
15:04:05
makomo
you can switch back to "emacs editing mode" (and back to "vim editing mode") at any time with a keybind
15:04:43
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?
15:05:02
elderK
Like, maybe it seems dumb but I want to spend my time learning and experimenting with CL, not with Emacs.
15:05:51
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)
15:06:03
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.
15:06:25
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
15:07:35
makomo
elderK: i'm not sure how long it took, but assume a few weeks or something (i guess?)
15:08:10
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
15:09:06
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
15:09:39
esper0s
i have been using emacs for a year now, loving it but oh my god the random buffer popping up is hideous
15:11:04
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
15:11:56
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
15:12:32
makomo
elderK: to install an emacs package you would use emacs' own commands, but to install a layer you would use spacemacs' commands
15:34:33
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.
15:34:43
pjb
elderK: Have a look at https://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/sedit/index.html
15:37:57
jcowan
and likewise cos and tan; arcsin and arccos return #C(nan, nan), but atan(inf) is, bizarrely, 1.5707963267949.
15:42:50
esper0s
thank you for the links the second book about text editors was god send as iam now writtin a text editor
15:46:42
esper0s
no iam alright with it, i have not started it yet as iam making a library of ansi ascape sequences first
15:48:29
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
15:49:25
jcowan
I'm trying to hold it down to "up" and "reverse video" on a few characters (to show that they are not literal)
15:53:12
pjb
How to represent buffers is less important than to define a good interface to this abstraction. You can change the implementation later.
15:59:38
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
15:59:44
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.
16:01:13
esper0s
so basically you can right applications in ecl and run tose applications with a c compiler like gcc?
16:02:07
jackdaniel
jebes: wrong, clasp compiles to llvm (it is interesting but it has different qualities which make it interesting)
16:02:38
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
16:04:07
jackdaniel
another interesting feature is that you may have Android applications which utilize ECL (see project eql5-android for examples)
16:09:14
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.
16:09:28
elderK
But learning both, gives you access to more concepts and ways of thinking, which hopefully makes you a better programmer.
16:10:04
jackdaniel
having access to more convenient tools may prove fatal if you need to write later in a language which doesn't provide them
16:12:17
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
16:12:50
esper0s
the language is just the syntax, but learning to represent concepts is the tricky part
16:12:52
jackdaniel
university is not for teaching you anything, only to show you directions in which you may teach yourself
16:14:35
minion
esper0s: please see SICP: The Structure and Interpretation of Computer Programs, a CS textbook using Scheme. Available under the CC-BY-NC Licence at <http://mitpress.mit.edu/sicp/> (HTML), <http://www.neilvandyke.org/sicp-texi/> (Texinfo), and <http://twb.ath.cx/ebooks/sicp.pdf> (PDF). Video lectures are available under the CC-BY-SA licence at <http://swiss.csail.mit.edu/classes/6.001/abelson-sussman-lectures/>
16:15:06
jackdaniel
this book is in scheme, but also covers many important subjects in programming and computer science
16:15:57
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
16:16:49
jackdaniel
I've said, that following assignments is not enough, not that it is unnecessary, make no mistake
16:17:03
esper0s
a terminal application to practice touch typing, a text editor and a dynamic interface to change the termios driver attributes
16:18:23
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.
16:18:51
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
16:19:12
jackdaniel
it is simply cheaper to build toasters on arm chips than using atmega chips and similar
16:19:38
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.
16:20:30
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?
16:20:35
makomo
whew, imagine connecting to your microwave that's running CL using SLIME from emacs :-D
16:34:22
elderK
Guys, any tips on how to approach the understanding of this macro? https://github.com/frodef/binary-types/blob/9ec42042a50403961c08179a892ae3de725b1d7a/binary-types.lisp#L545
16:37:10
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
16:37:12
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.
16:38:20
pjb
elderK: you know, you're not the first one to have those problems. They have been solved! in emacs.
16:41:19
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)))))
16:42:26
pjb
but indeed, it'd be better to implement a little function that would allow you to hide or show each subexpression at will.
16:44:11
pjb
elderK: yes, slowly, write tools and commands to build up and customize your environment.
17:27:44
elderK
So, I'm slowly managing to understand it. Just by reading it... Force of will and all that.
17:27:57
elderK
It's made harder because it seems that he's used tabs in his source. But, inconsistently.
17:34:59
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?
17:35:29
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.
17:36:20
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.
17:36:44
elderK
I /should/ be working on sleep. But, iono, I feel oddly compelled to keep reading. :)
17:56:49
jebes
with the direction the IT industry is going, we just need to rebrand it as something else
18:26:38
jackdaniel
Java is a decent language. it is not CL, but isn't as bad as people try to shame it
18:27:59
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"
18:30:21
jcowan
The R2RS report on Scheme was subtitled "An Uncommon Lisp". A stupid piece of snark IMAO, and I'm glad we dropped it.
18:31:44
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.
18:37:56
elderK
This really does seem kind of.. confusing: http://www.lispworks.com/documentation/lw70/CLHS/Body/m_defstr.htm
18:38:03
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
18:38:09
elderK
Early in the description, it states that it creates readers for the slots, and they are setfable
18:38:38
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.
18:38:58
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".
18:39:43
elderK
I thought like, if you wanted to do (setf (something) value), you had to have a setf expansion?
18:40:13
pjb
elderK: setf can work in other ways than with a setf function or a defsetf or setf expander.
18:40:17
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.
18:40:50
pjb
elderK: this is a door open to let implementation optimize structures in very special ways.
18:41:26
pjb
Some old implementations took advantage of it. Modern implementations tend to define structures as subclasses of clos objects.
18:41:28
makomo
elderK: a "setf function" and a "setf expander" are just two ways of providing a "place" for SETF to operate on
18:43:52
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.
18:45:02
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
18:45:40
elderK
It's not really doing anything all that complicated, not really. Just, very... clumped together.
18:45:46
makomo
or if the macro is simple enough, a couple of examples with their expansions or something
18:46:07
elderK
And ideally, you'd have all of those figured out before you started writing the macro, anyway.
18:46:29
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.
18:48:09
elderK
Or rather, the goalpost changed. It is complete. But there are signs that it was meant to do more.
19:02:24
elderK
Question: If a macro is meant to evaluate one of its arguments, does it have to call eval on it?
19:03:11
makomo
elderK: good question. you're referring to evaluating the argument whilst computing the expansion, right?
19:03:39
makomo
(instead of arranging for the argument to be evaluated within the generated expansion)
19:03:49
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."
19:04:01
pjb
elderK: no it doesn't have to evaluate, but ensure that the argument is evaluated at run-time.
19:04:26
makomo
elderK: you're thinking of the latter then. the former would be macroexpansion-time evaluation, which is a rare thing to do
19:04:29
pjb
elderK: in general it would be difficult to evaluate something at macroexpansion time, because EVAL doesn't take an environment argument.
19:05:32
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?
19:05:35
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.
19:06:34
pjb
(defmacro set-double (var expression) "evaluates the expressions and binds the resulting value to the variable var" `(setf ,var ,expression))
19:06:43
pjb
(defmacro set-double (var expression) "evaluates the expressions and binds the resulting value times 2 to the variable var" `(setf ,var (* 2 ,expression)))
19:06:56
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"?
19:07:36
makomo
what pjb just described is the case when the arguments /are/ evaluated (by arranging for them to be evaluated within the expansion)
19:07:44
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.
19:08:18
makomo
elderK: to "arrange for something to be evaluated" means to splice it into the proper places within the expansion
19:08:39
elderK
Okay, and to have it /not evaluated/ would mean to splice it in, but make sure it's quoted when spliced?
19:08:57
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.
19:09:35
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.
19:10:51
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?
19:11:16
makomo
elderK: if they do so, the expansion will be incorrect, as the NAME will be the actual form (MAKE-SYMBOL ...)
19:11:35
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?
19:12:43
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.
19:13:09
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
19:13:17
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 :-)
19:13:49
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
19:13:49
elderK
pjb: I appreciate you trying to help but code dumps like that in IRC are not all that helpful.
19:13:58
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)
19:14:05
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 |#
19:14:44
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
19:14:45
pjb
elderK: Sorry, I don't see the difference between 300 characters of english and 300 characters of lisp.
19:15:23
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.
19:15:48
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
19:16:07
makomo
but evaluating at macroexpansion-time is so rare that we take that sentence to mean the conventional thing that everyone just described
19:16:12
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.
19:17:07
elderK
makomo: Thank you. And aye, I should be clearer. White_Flame, that's how I see macros too.
19:17:28
pjb
elderK: but don't you already have a command that does that automatically? I thought vim was scritable too.
19:18:00
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.
19:18:04
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")
19:18:06
pjb
elderK: see for example: com.informatimago.common-lisp.cesarum.utility:define-structure-class
19:19:26
pjb
(defpackage "COM.INFORMATIMAGO.MY.CURRENT.PROGRAM" (:use "COMMON-LISP" "COM.INFORMATIMAGO.COMMON-LISP.CESARUM.UTILITY)) (in-package "COM.INFORMATIMAGO.MY.CURRENT.PROGRAM")
19:20:04
pjb
elderK: Since most of my code is written in libraries, it cannot use package nicknames.
19:22:16
elderK
I kind of want to reimplement binary-types as a learning exercise. I'd like to see if I can do it cleaner.
19:23:03
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?
19:23:56
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.
19:24:08
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.
19:25:24
elderK
So, is there anything wrong with using macros as a way to conveniently destructure stuff?
19:28:40
pjb
quicklisp uses it to log the packages that are loaded and display the dots when compiling, I believe.
19:29:04
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?
19:29:31
elderK
Probably best to write it as a normal function though, right? Maybe local to the macro itself.
19:29:58
pjb
again, macros are functions like other functions, So you can refactorize them as you wish and would do for other functions.
19:30:33
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?
19:30:39
pjb
And if you re-read my example substituting backquote with list and other abstract functions I gave yesterday, it more readable.
19:31:10
elderK
I would have broken the expansion process into a lot of little helper functions, that would be available at compile-time.
19:32:41
elderK
It's a lot easier for me to deal with lots of small functions, than one giant overnested one.
19:33:35
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.
19:34:02
elderK
The deeper you are nested when you define your functions, the less space you have per line for the body of a function.
19:34:38
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 :)
19:35:14
elderK
equwal: Longer vs Wider? :) I don't own the LoL book yet, I am unfamiliar with those macros.
19:36:12
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
19:37:17
makomo
equwal: yeah, same. i read it already, but i wanted to have a deadtree copy as well :-D
19:38:35
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.
19:39:05
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?
19:39:51
makomo
equwal: i also read all of my books in digital form most of the time, but this one i wanted to have irl :-)
19:40:12
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?
19:41:22
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.
19:42:29
pjb
(cond (condition1 expr11 expr12 … expr1n) (condition2 expr21 expr22 … expr2n) … (conditionp exprp1 exprp2 … exprpn)
19:43:00
pjb
also, there's no difference in memory and processing time between an a-list and a p-list.
19:43:18
elderK
equwal: I find electronic books to be a lot better than deadtree these days, mostly because of the ability to zoom :)
19:43:57
pjb
You can even define a macro (cond. test1 => a b c test2 => d e test3 => f g h else i j)
19:44:22
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.
19:46:37
jackdaniel
I'm talking about his personal aesthetics, not yours, so you can't informely say nope (unless you are the same person)
19:47:17
pjb
or (if* condition then something else) if you prefer. or (if* condition else something) for unless
19:48:23
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)).
19:52:19
NoNumber
Is PCL still a recommended text here in #lisp? Want to make sure I'm not wasting my time going through it.
19:52:30
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))
19:55:58
elderK
I spent a lot of time playing in Scheme. Lovely language. Great implementations with fantastic communities.
19:59:14
equwal
I don't know if I want that. I like scheme because it is a good simple, small language.
19:59:52
elderK
Silly subjective reasons, too. Like, I like define :) and the way predicates and things are denoted.
20:01:01
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.
20:01:47
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?
20:05:31
equwal
(defmacro y (lambda-list-args specific-args &rest code) `(labels ((f ,lambda-list-args . ,code)) (f ,@specific-args)))
20:19:00
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.
20:19:17
aeth
Both Arc and Clojure decided concise names were great and that everyone should save 3 keystrokes.
20:19:58
pjb
actually, you may be saving more keystrokes with the longer names, and emacs completion than with the short names, that are more ambiguous.
20:21:06
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
20:22:40
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?
20:23:06
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) (...))
20:23:07
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.
20:24:27
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.
20:24:48
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
20:25:17
pjb
old names were short because 6 characters stood in a word (36-bit words, 6-bit per character).
20:25:53
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.
20:27:52
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.
20:28:06
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
20:32:00
anamorphic
Is there some reason in that example code for defsetf that they need to not export a keyword?
20:33:40
pjb
No. it's purely incidental. Perhaps they hadn't completed the specification of &key yet when the wrote the example.
20:34:10
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.
20:37:11
makomo
elderK: regarding the named let, Let Over Lambda does exactly that :-) (implement it as a macro)
20:39:15
elderK
makomo: I imagine you could synthesize named-let with clever use of block or tagbody or something
20:41:39
equwal
Loop is pretty imperative. I like series but there are too many restrictions that make is difficult to know if something will work.
20:42:08
pjb
but you may want to transform the recursion into an interation to avoid using too much stack.
20:43:40
elderK
Well, I was thinking of something that... wouldn't use recursion unless it had to :)
20:44:40
equwal
Chapter 4 is great for getting into read macros. Doesn't require lots of experience.
20:48:24
equwal
Why not just read the first first six chapters? At your level you might not get much from the two non-free chapters anyway.
20:48:37
elderK
I might try writing once-only myself for fun - but I need to really understand /exactly/ what it's doing, first.
20:48:55
makomo
elderK: i would still try just reading it. LoL was the 2nd CL book i started reading
20:49:23
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
20:50:24
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
20:50:42
equwal
makomo: You'd like OnLisp. The whole book is about macros like LOL http://www.paulgraham.com/onlisp.html
20:52:45
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)
20:53:00
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?
20:54:29
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"
20:55:05
makomo
so it might not be 100% correct, depending on the precise meaning you had in mind :-)
20:55:48
makomo
as ONCE-ONLY has to (1) be hygienic itself and (2) produce expanders which are hygienic
20:58:32
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
20:59:54
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 :-))
21:03:42
equwal
I wonder how to understand triple or more backquotes. Like how can I understand what ``````(,@,,@,,,@thing) would do?