freenode/#lisp - IRC Chatlog
Search
22:31:20
hydrocat
Hello everyone. I am trying to write a text tranformation program but I am not sure about all the things common lisp can do yet. Any recommendation on learning resources ?
22:32:24
hydrocat
I've found a book called "Practical common lisp" but I'd like your opinion on it :)
22:34:39
hydrocat
But for example, to read text from a file, I am using read-char. I mean, it can be done but maybe there would be a better way.
22:35:31
DataLinkDroid
hydrocat: PCL is a decent place to start, especially if (as seems to be the case) you already know something of one or more other languages.
22:38:25
hydrocat
okay, then I have a more specific question, more personal if you will. In the process of implementing a lexer, I am unsure wether I should make a token generic class and implement it multiple times or simply use symbols.
22:43:03
White_Flame
well, having just implemented a lexer, I made each token a list. (:token "foo") (:punc "(") (:whitespace " ") etc
22:43:24
White_Flame
very easy to construct & deconstruct, and Lisp has good support for ad-hoc data in lists
22:47:23
White_Flame
each package has its own instance of symbols. So lexer:foo is not the same symbol as parser:foo, or cl-user:foo. Keywords are visible and resolve to the same symbol from any package
22:47:44
White_Flame
they're intended for data that's broadly visible and self-contained across systems
22:50:01
DataLinkDroid
hydrocat: symbols beginning with a colon are "keyword" symbols belonging to the keyword package
22:50:30
aeth
So if you wanted to compare them you'd have to do something like get the symbol name and reintern them, or get the symbol-name and do a string=
22:50:39
White_Flame
hydrocat: it all depends. I woudln't say to avoid it. But you'll learn the ins & outs with use
22:51:09
White_Flame
source code is made of non keywords. in (defun foo () ..), "FOO" is interned in the package that was read in
22:51:30
aeth
e.g. LOOP takes symbols from any package so (loop for x in bar do (print x)) and (loop :for x :in bar :do (print x)) both work. Most macros will just take keywords, though, because it makes the implementation simpler and the written code more readable
22:51:30
White_Flame
so especially in macros where you're building up source code from symbols, those need to be properly packaged symbols in order to reference the right thing
22:54:23
hydrocat
aeth: But then, wouldn't the loop macro fail in some situations since it is taking symbols from any package ?
22:55:11
aeth
hydrocat: the loop macro probably is doing something like this: (eql (intern (symbol-name symbol) some-package) 'some-package:foo) instead of (eql symbol 'foo)
22:55:45
DataLinkDroid
hydrocat: The LOOP macro would not use the value associated with the symbol, but only its name.
22:56:20
aeth
Oh, and since LOOP is built-in and commonly used, there might also be some internal implementation-specific symbol-name-equal
22:57:18
aeth
(Practically, that wouldn't differ too much from doing string= on the symbol-name, though)
2:35:42
no-defun-allowed
Is there a name for the (somewhat more general) phenomenon described in https://web.archive.org/web/20001030070110/http://www.ai.mit.edu/docs/articles/good-news/subsubsection3.2.2.4.html?
2:36:36
no-defun-allowed
That's where you have code like that matrix addition code which you wouldn't ever use, but you would maybe show off with.
3:12:10
no-defun-allowed
There isn't. I'm talking about good looking code that performs terribly, like reversing a list using APPEND or that Haskell "quick"sort function.
3:17:00
no-defun-allowed
Marginally better is the Sieve of Eratosthenes, which is at least 5 times longer: https://rosettacode.org/wiki/Sieve_of_Eratosthenes#Haskell
3:17:18
no-defun-allowed
But I think we're talking over each other on what I'm looking for, so never mind.
3:20:37
no-defun-allowed
Sure. But I still wouldn't use the former if I needed to find a lot of primes fairly quickly.
3:23:12
no-defun-allowed
There's a few other implementations that don't use do, but I still don't think that's relevant to my question.
4:34:45
no-defun-allowed
cl-trie has...interesting documentation. I tried to make an instance of cl-trie:trie and got a warning: "Key for trie not provided, possibly an overlook! See documentation for more information"
4:36:01
no-defun-allowed
So I did, and the example suggests I should add the initargs :verbose nil to muffle the warning.
4:36:27
beach
no-defun-allowed: You will find some very inefficient code in my repositories. For example, when I write random tests for a data structure, there is usually a "simple" version of it that uses the simplest data structure I could think of, and a "standard" version that is meant for production. I then generate random tests to compare the results of the two.
4:38:23
beach
But it could have taken as an example by rpg: "This really occurred in some code I've seen"
4:39:07
beach
So, if taken out of context, it might pass as code written by a very incompetent programmer.
4:40:37
no-defun-allowed
I ask because it's not uncommon to see simple code like that when "marketing" languages. If I get around to that, it would be polite to add a footnote: "This is an example of a <name>, which may or may not be representative of what you write in larger programs."
4:42:55
beach
Representing a matrix as a list of lists makes for some beautiful code for (as I recall) transposing the matrix.
4:44:55
beach
"Sir, I just compared the performance of your code to a C version of it. The C version is 1000 times faster. Does that mean that the language you are teaching us is useless in industry?"
4:45:01
no-defun-allowed
Agreed. It would probably be better to not include inefficient but "cute" code in that kind of material then.
4:52:50
no-defun-allowed
(And that didn't stop Python or any other scripting language, unfortunately.)
4:53:25
fiddlerwoaroof
At this point, consumer hardware is fast enough that inefficient algorithms often don't matter
4:58:10
aeth
fiddlerwoaroof: In practice, though, you'd use someone's matrix library, and the matrix library would make the correct decisions for the domain.
4:58:59
fiddlerwoaroof
aeth: matrix math is relatively rare, unless you're in a data science or game development context
4:59:18
aeth
Well, I mean, more likely, something other than matrices, like e.g. some standard GUI app or whatever
4:59:58
aeth
Imo, it's not because of the hardware that most programmers don't have to think about efficiency, it's because the work has already been done. Even to some extent us with SBCL
5:00:02
fiddlerwoaroof
Yeah, but my experience is that it's usually something like Rails or Spring which are tremendously inefficient
5:00:56
aeth
On servers, yes, you can do that, and if the efficient solution takes 5x longer to write than Rails, then using Rails makes sense.
5:01:16
aeth
I mean, it'll hurt people like me inside a bit to write inefficient code, but there are deadlines to meet
5:01:50
aeth
I think the real question is why there isn't a CL Rails, which probably should be able to be 10x faster without sacrificing developer productivity (besides unfamiliarity with the environment, of course)
5:03:09
aeth
It is very noticable when you're making your user load something in 3 seconds in JS rather than loading something instantly (* before network latency is taken into account, which should be < 100 ms afaik)
5:04:14
aeth
Sure, go for developer productivity over efficiency, but only when your servers are paying the cost, not the user with a 5 year old tablet or a 15 year old PC.
5:05:36
aeth
Fortunately (if JavaScript isn't involved) pretty much any end-user task on a PC is fast enough even on 10 year old hardware unless it's demanding like games or some professional tool.
5:06:31
aeth
I think the only thing that the user would notice as the difference between a CL GUI and an optimized C GUI is RAM usage, even if the former is 10x slower.
5:08:29
aeth
(And a lot of that speed loss is safety, i.e. not segfaulting randomly, which the user certainly notices.)
6:12:44
LdBeth
I guess many interpreted languages have claimed they've suppressed C on performance :*
6:18:18
beach
There is no such thing as an interpreted language. Interpretation is a property of the implementation.
6:31:05
fiddlerwoaroof
I'd think that certain language features (f-exprs, maybe?) preclude compilation in a meaningful sense
6:31:13
jackdaniel
if the specification says: "code is always interpreted compiling it is a spec violation" then yes ;-)
6:32:37
fiddlerwoaroof
But, if the meaning of a symbol always depends on the dynamic context and that context can always be changed arbitrarily by a function's caller, you couldn't optimize at all
6:32:41
beach
Sure, some languages make it very hard to write a compiler. But history shows that what is possible can change over time as new techniques are invented.
6:33:05
fiddlerwoaroof
(my guess is that such a language would be extremely painful to write as well, but...)
6:34:22
no-defun-allowed
I would guess self-modifying Brainfuck is a hard language to compile, at least if you ignore JIT/dynamic recompilation techniques.
6:35:14
jackdaniel
arguably any language is hard to compile, because efficient compilation is not easy ;-)
6:35:49
fiddlerwoaroof
beach: would I use Trucler if I wanted a macro to have access to declarations?
6:44:48
beach
fiddlerwoaroof: Currently, heisig is the one maintaining Trucler, and he is also writing backends for various existing Common Lisp implementations. The best thing would be to check with him what is possible.