<aeth>
I have to manually iterate the lists so it terminates one after the list end instead of at the list end.
<aeth>
Basically I assume that (code-char 0) is invalid, so when I come across a symbol that's not a keyword (i.e. a variable) then I write (code-char 0) and I push the variable-name to an internal list in write-html, which is returned at the end (in reverse order). Then I write the string, split on (code-char 0)s with calls to (write-html ,variable ...) in between the splits.
_leb has quit []
<aeth>
So, effectively, what the macro generates is: if it's not (code-char 0) then it writes the string range up until that point and if it is, then it writes the original symbol it encountered, which is assumed to be a variable.
<aeth>
If no variables are used, then it just writes a constant string, which is going to be the most efficient. The next most efficient will be to precalculate as much as possible.
motte has quit [Ping timeout: 265 seconds]
motte has joined #lisp
t58 has quit [Quit: Night]
cosimone_ has joined #lisp
cosimone has quit [Ping timeout: 276 seconds]
casedeg has joined #lisp
cdegroot has quit [Read error: Connection reset by peer]
Nomenclatura has joined #lisp
karlosz has joined #lisp
EvW has quit [Ping timeout: 245 seconds]
bitmapper has quit [Ping timeout: 240 seconds]
Nomenclatura has quit [Quit: q]
karlosz has quit [Quit: karlosz]
stepnem has quit [Ping timeout: 265 seconds]
stepnem has joined #lisp
catchme has quit [Quit: Connection closed for inactivity]
cosimone_ has quit [Quit: Terminated!]
ravenousmoose has joined #lisp
FreeBirdLjj has joined #lisp
ravenousmoose has quit [Ping timeout: 276 seconds]
FreeBirdLjj has quit [Remote host closed the connection]
FreeBirdLjj has joined #lisp
FreeBirdLjj has quit [Ping timeout: 265 seconds]
semz has quit [Ping timeout: 245 seconds]
FreeBirdLjj has joined #lisp
Josh_2 has quit [Remote host closed the connection]
clothespin has joined #lisp
semz has joined #lisp
semz has joined #lisp
libertyprime has joined #lisp
sjl has joined #lisp
karlosz has joined #lisp
FreeBirdLjj has quit [Ping timeout: 268 seconds]
FreeBirdLjj has joined #lisp
libertyprime has quit [Quit: Lost terminal]
libertyprime has joined #lisp
reggie_ has joined #lisp
reggie__ has quit [Read error: Connection reset by peer]
torbo has quit [Remote host closed the connection]
FreeBirdLjj has quit [Remote host closed the connection]
rople has joined #lisp
nowhere_man has joined #lisp
rople has quit [Ping timeout: 265 seconds]
nowhereman has quit [Ping timeout: 276 seconds]
zdm has joined #lisp
orivej has quit [Ping timeout: 264 seconds]
rople has joined #lisp
zaquest has quit [Remote host closed the connection]
libertyprime has quit [Ping timeout: 240 seconds]
libertyprime has joined #lisp
ravenousmoose has joined #lisp
abhixec has joined #lisp
karlosz has quit [Quit: karlosz]
ravenousmoose has quit [Ping timeout: 276 seconds]
ravenousmoose has joined #lisp
lxbarbosa has joined #lisp
<lxbarbosa>
one thing that I miss in Python/Golang is Lisp -p predicate vars... so clean!
<aeth>
in other languages I tend to replace that with is_ or has_, although not consistently
<aeth>
in some languages if you end with "p" people might think you're talking about pointers
<aeth>
I generally prefer suffixes to prefixes because then they don't affect an alphabetical sort
dale has joined #lisp
<lxbarbosa>
aeth: yep, Ive tried that, but someone said it aint pythonic :D
Bike has quit [Quit: Lost terminal]
Lord_of_Life_ has joined #lisp
Lord_of_Life has quit [Ping timeout: 265 seconds]
zdm has quit [Remote host closed the connection]
Lord_of_Life_ is now known as Lord_of_Life
<fiddlerwoaroof>
Hi
superkumasan has quit [Ping timeout: 276 seconds]
yoja has joined #lisp
ravenousmoose has quit [Ping timeout: 276 seconds]
yoja has quit [Ping timeout: 265 seconds]
<no-defun-allowed>
lxbarbosa: "not pythonic" should be treated as a compliment.
gravicappa has joined #lisp
<lxbarbosa>
no-defun-allowed: lol
abhixec has quit [Quit: leaving]
libertyprime has quit [Ping timeout: 240 seconds]
ebzzry has quit [Ping timeout: 250 seconds]
libertyprime has joined #lisp
iovec has quit [Quit: Connection closed for inactivity]
Josh_2 has joined #lisp
sindan has quit [Remote host closed the connection]
raghavgururajan has quit [Read error: Connection reset by peer]
sindan has joined #lisp
duuqnd has joined #lisp
karlosz has joined #lisp
karlosz has quit [Client Quit]
karlosz has joined #lisp
lxbarbosa has quit [Remote host closed the connection]
troydm has quit [Ping timeout: 240 seconds]
<beach>
Good morning everyone!
<Josh_2>
Mornin'
<LdBeth>
Good eve
troydm has joined #lisp
dddddd has quit [Remote host closed the connection]
lxbarbosa has joined #lisp
<Josh_2>
Trying to convince a permanent C++ user to try out CL
<Josh_2>
I don't get why people are so caught up about the syntax
<no-defun-allowed>
It's probably an excuse for something else, especially with their type<T<T2> > shenanigans.
<beach>
Josh_2: If that is what you are being told, I think the person is giving you an excuse that just isn't true.
<Josh_2>
Well one person has said they will try
<beach>
Josh_2: There are very strong psychological forces at work that make people resist anything new.
<beach>
Josh_2: So their subconscious will come up with any excuse to avoid the new thing.
<Josh_2>
Cognitive dissonance oof
<beach>
Josh_2: They are typically not even aware that this is what they are doing.
dale has quit [Quit: My computer has gone to sleep]
<beach>
Josh_2: Some bad cases will come up with ridicule such as "only bald people use Lisp".
<beach>
Josh_2: In general, I recommend that you avoid trying to convince people. It is usually a waste of time.
<no-defun-allowed>
Wait, what‽
<no-defun-allowed>
beach: "Bald people" is a new one to me. I've heard about beard length before though.
<beach>
It is what I could come up with, given that I haven't finished my coffee yet.
<Josh_2>
I don't know about not trying to convince people
<beach>
Besides, beard length could be a sign of wisdom.
<no-defun-allowed>
Fair enough, I was worried that was real.
<Josh_2>
i'd rather try ¯\_(ツ)_/¯ I think CL is cool and I reckon others will
<beach>
Josh_2: Highly unlikely if they are just being told about it.
<beach>
Josh_2: The only thing I have found to work is to show real result from very productive work.
<no-defun-allowed>
(For example, http://i.imgur.com/HLp8z11.jpg for GNU/Linux distributions. I think beards are just a general computer science thing.)
<Josh_2>
My beard must be very long oof
<beach>
All I am saying is that the worst offenders, i.e. the ones with the "closest mind set" (terminology by Carol Dweck), will go to any length to convince their entourage NOT try anything new. Ridicule is one such tactic. And those worst offenders are often "alpha males", so they have great influence on others.
<Josh_2>
Absolute chads
<no-defun-allowed>
Back to the point, people have excuses and you might be more productive working on your own stuff. Then you can show them, then they might be convinced, else you can laugh at them in your head for willingly wasting their own resources.
<Josh_2>
can't say I've met many brogrammers
<no-defun-allowed>
You should try a mirror.
<Josh_2>
Well I wasn't gonna say that was I
<Josh_2>
ʕ·͡ᴥ·ʔ
<beach>
Josh_2: I recommend the writings (and YouTube presentations) by Carol Dweck. Once you understand the psychological forces involved, perhaps you can also understand how to work around them.
<Josh_2>
She seems very self helpy and I'm not so into that crowd
gareppa has quit [Remote host closed the connection]
igemnace has joined #lisp
scymtym has joined #lisp
Cymew has joined #lisp
varjag has joined #lisp
fanta1 has joined #lisp
manualcrank has quit [Quit: WeeChat 1.9.1]
ralt has joined #lisp
nowhere_man has joined #lisp
scymtym_ has joined #lisp
scymtym has quit [Ping timeout: 250 seconds]
nowhere_man has quit [Ping timeout: 240 seconds]
esrse has joined #lisp
igemnace has quit [Ping timeout: 250 seconds]
igemnace has joined #lisp
ljavorsk_ has joined #lisp
<jackdaniel>
I'm definetely not bald, I have longer hair than my wife :)
space_otter has quit [Remote host closed the connection]
DGASAU has quit [Read error: No route to host]
DGASAU has joined #lisp
zdm has joined #lisp
<semz>
"Nobody else has ever been able to replicate it" is a pretty big issue...
jamzattack has joined #lisp
hhdave has joined #lisp
karlosz has quit [Quit: karlosz]
ltriant has quit [Quit: leaving]
<beach>
semz: There is independent research that suggests that expertise requires hard work. I recommend a book entitled "peak" by Anders Ericsson.
rople has quit [Ping timeout: 276 seconds]
<beach>
Note, though, the direction of the implication arrow. Hard work does not necessarily result in expertise, as we often see in the domain of software development.
<ralt>
no, but the reverse is usually true: expertise requires hard work
<beach>
That's what I just said.
<ralt>
which I guess is...
<ralt>
yeah, that :)
<ralt>
it's monday morning
<beach>
I know.
jamzattack has left #lisp ["ERC (IRC client for Emacs 26.3)"]
rople has joined #lisp
<schweers>
So the question might be: how do we prevent people from doing hard work which does not result in, or otherwise further, expertise?
<beach>
That is indeed *the* question.
<White_Flame>
I tend to have a positive view of apprenticeship
<beach>
jackdaniel: The baldness thing was an example of how preposterous the claims of these closed-minded people might be, and how they will do anything (including ridicule) to avoid learning new things. And you are a good example of how preposterous that claim is.
hhdave has quit [Read error: Connection reset by peer]
<White_Flame>
you're not just doing work, but working with somebody, seeing a direct example of how they benefit from the work and tune it to positive effects
hhdave has joined #lisp
<White_Flame>
also I have 2 beards, that makes me double something
<jackdaniel>
beach: there are many rude people whose behavior doesn't need to be explained with complicated theories, I'm sure that if they have no problem with saying "only bald people use lisp" then leaving lisp of it and saying "bald people are <whatever>" is as likely if they do not like the person in question (and 'baldness' could be replaced by any visible trait of said person)
<schweers>
I have a quick lisp question. I have a pathname object and want to construct a new one based on it. In UNIX I’d just append "../somedir" to get the directory part. What is the most portable (both concerning lisp implementations and OSes) way of doing so? Using a "/" character is obviously not the best move here. I could use nested MERGE-PATHNAMES, but that just seems wrong and overblown. Is using '(".." "somedir")
<schweers>
part portable?
<schweers>
I guess I’m mostly worried about ".." being a unixism.
<Shinmera>
pathname-utils has a bunch of tested functions to help with that stuff.
<Shinmera>
Colleen: tell schweers look up pathname-utils
<Shinmera>
Feel free to copy-paste what you need from the sources if you don't want the dep.
ljavorsk__ has joined #lisp
mn3m has quit [Remote host closed the connection]
<schweers>
Shinmera: Thanks. I just took a look at the code and found out that :up can be a directory part. I guess this alone solves my problem.
patrixl has quit [Read error: No route to host]
ljavorsk_ has quit [Ping timeout: 240 seconds]
patrixl has joined #lisp
gareppa has quit [Quit: Leaving]
<Cymew>
What are the depenencies anyway?
<schweers>
Cymew: in case you meant pathname-utils, the library itself would be a dependency.
<ralt>
I think what you'd want is something like (defun merge (orig &rest pathnames) (reduce #'merge-pathnames pathnames :initial-value orig))
<schweers>
ralt: that wouldn’t have saved me from the issue of ".." being a unixism.
iovec has quit [Quit: Connection closed for inactivity]
<schweers>
Not that my code will ever run on anything other than linux ...
<ralt>
ah, right, pathname-utils provides the PARENT function for that then
<schweers>
which in turn taught me about the existence of the :UP part of a directory.
<thijso>
I find that is often a good way to learn things... read other code
<thijso>
although you might pick up some less ideal things if you look at code that doesn't follow conventions etc
zaquest has joined #lisp
<saturn2>
which open source lisp projects have the most ideal code?
<jackdaniel>
(print "Hello world") ; bsd-2-clause
<jackdaniel>
↑
<saturn2>
thanks, i will study this
<Shinmera>
That's not ideal, the print isn't necessary!
<jackdaniel>
I'm aiming at the standard-output
<jackdaniel>
if there were no print I would have no guarantee that anything appears on the screen
<Shinmera>
you don't have that guarantee anyway, the standard doesn't specify screens ;)
<jackdaniel>
sure, still putting just a string would be less ideal, by screen I've meant 'standard output' of course :)
<beach>
saturn2: What meaning do you put into "ideal" in this context?
<saturn2>
whatever your own opinion is
<beach>
I suggest you look at Eclector then.
<beach>
It is easy to understand what it does (it is the Common Lisp READ function with extensions).
<beach>
It is a good example of Common Lisp object-oriented programming using CLOS.
<beach>
It is well tested and well documented.
<beach>
And it is written so that clients can customize its behavior.
<saturn2>
ok, thanks
<schweers>
Thank you duckduckgo for telling me about some spaceship in the Marvel Cinematic Universe, before telling me about the lisp project :D
<beach>
saturn2: And it is actively developed and maintained, so you can ask questions about it. Either here or in #sicl.
froggey has quit [Ping timeout: 240 seconds]
froggey has joined #lisp
prite has joined #lisp
jmercouris has joined #lisp
<shka__>
saturn2: if you are looking for a style to imitate, beach writes cleanest code
gareppa has joined #lisp
gareppa has quit [Remote host closed the connection]
jmercouris has quit [Ping timeout: 240 seconds]
elinow has joined #lisp
frgo_ has joined #lisp
m00natic has joined #lisp
frgo has quit [Ping timeout: 245 seconds]
prite has quit [Ping timeout: 240 seconds]
frgo_ has quit [Ping timeout: 276 seconds]
amerigo has joined #lisp
BooAA has joined #lisp
frgo has joined #lisp
mn3m has joined #lisp
_whitelogger has joined #lisp
<Cymew>
schweers: Ah, I see.
EvW has joined #lisp
BooAA has quit [Ping timeout: 260 seconds]
ljavorsk_ has joined #lisp
zdm has quit [Remote host closed the connection]
gravicappa has quit [Ping timeout: 276 seconds]
vlatkoB has joined #lisp
vlatkoB has quit [Client Quit]
ljavorsk__ has quit [Ping timeout: 268 seconds]
motte has quit [Ping timeout: 265 seconds]
motte has joined #lisp
EvW has quit [Ping timeout: 252 seconds]
rople has quit [Ping timeout: 240 seconds]
EvW has joined #lisp
ebrasca has joined #lisp
esrse has quit [Ping timeout: 268 seconds]
red-dot has quit [Quit: Going offline, see ya! (www.adiirc.com)]
wxie has joined #lisp
frgo_ has joined #lisp
frgo_ has quit [Remote host closed the connection]
frgo_ has joined #lisp
isBEKaml has quit [Quit: leaving]
frgo has quit [Ping timeout: 265 seconds]
zaquest has quit [Remote host closed the connection]
frgo_ has quit [Remote host closed the connection]
frgo has joined #lisp
EvW has quit [Quit: EvW]
EvW1 has joined #lisp
zaquest has joined #lisp
<lxbarbosa>
I did know that Reddit was written in Lisp before switching to Python then to React... :d
<lxbarbosa>
leb has joined #lisp
cosimone has joined #lisp
prite has joined #lisp
vlatkoB has joined #lisp
motte has quit [Quit: WeeChat 1.9.1]
leb has quit [Ping timeout: 276 seconds]
cosimone has quit [Remote host closed the connection]
cosimone has joined #lisp
ljavorsk_ has quit [Ping timeout: 240 seconds]
doublex has quit [Ping timeout: 265 seconds]
vaporatorius has quit [Read error: Connection reset by peer]
doublex has joined #lisp
vlatkoB has quit [Read error: Connection reset by peer]
lucasb has joined #lisp
dddddd has joined #lisp
wxie has quit [Remote host closed the connection]
wxie has joined #lisp
vlatkoB has joined #lisp
Bike has joined #lisp
longshi has joined #lisp
Bike has quit [Remote host closed the connection]
andrei-n has joined #lisp
vlatkoB has quit [Remote host closed the connection]
vlatkoB has joined #lisp
Kevslinger has joined #lisp
xkapastel has joined #lisp
Bike has joined #lisp
wxie has quit [Ping timeout: 245 seconds]
longshi has quit [Quit: WeeChat 2.5]
gareppa has joined #lisp
gareppa has quit [Remote host closed the connection]
longshi has joined #lisp
Bike has quit [Remote host closed the connection]
Bike has joined #lisp
xlxs4 has joined #lisp
decent-username has joined #lisp
<decent-username>
Good morning. I'm pretty close to finishing the Line Of Sight algorithm for my rogue like. Right now I have a 2D array that cotains objects of typr 'cell which encapsulate things like "is this cell visible". My question is: How can I change the printed representation of an object?
LiamH has joined #lisp
<Bike>
define a print-object method specialized on the cell class.
<decent-username>
ok, let's hope that allows me to use the slots of the object in the name.
red-dot has joined #lisp
<decent-username>
*for the printed representation
<Bike>
assuming you have some way to get the slots, sure why not
cosimone has quit [Quit: Terminated!]
mn3m has quit [Read error: Connection reset by peer]
jmarciano has joined #lisp
xlxs4 has quit [Quit: Leaving]
<White_Flame>
it's a plain function, you could look up stuff in external tables as well; it doesn't need to be self-contained on the object itself, if it's easier for you to manage differences there
<Xach>
vms14: the evaluation rules have to be memorized and internalized if you want to use it effectively. they are not too complicated but you *must* know them by heart or you will get confused.
<LdBeth>
I thought it is a CL version of unix who command
<Xach>
LdBeth: NO
hiroaki_ has joined #lisp
andrei-n has quit [Remote host closed the connection]
andrei-n has joined #lisp
<dlowe>
you can be forgiven for thinking so :p
jmercouris has joined #lisp
<Shinmera>
if I remember correctly even Edi recommended against using cl-who
<vms14>
macro-html depends on named-readtables and shadows map and time as those symbols collide with HTML element names
<vms14>
oh, does not support html5 tags
<aeth>
cl-who afaik walks through all of your source code within the macro and substitutes anything inside (htm ...) with the appropriate transformations to string writing functions... so it's possibly the most efficient approach, but I personally hate when there's magic like that.
<dlowe>
I think you will get an unambiguous, reliable answer by trying them
ebzzry has quit [Ping timeout: 246 seconds]
<aeth>
Having to hardcode HTML tags doesn't seem like a robust approach because, as I said, it's a "living standard" so now you have to constantly update your library. You do have to hardcode what the empty elements like <br> are, though.
andrei-n has quit [Read error: Connection reset by peer]
<aeth>
s/as I said/as I said the other day/
duuqnd has quit []
<aeth>
It seems really weird to define a macro for every html element instead of just using keywords and handling it with one macro like (with-html (stream) (:foo 42)) and, as you noticed, it does have potential name conflicts
<vms14>
aeth: use capture s/(as I said)/$1 the other day/
<vms14>
xD
cosimone_ has quit [Read error: Connection reset by peer]
Lycurgus has quit [Quit: Exeunt]
<aeth>
and when you have each thing be its own macro, you have to do something like rely on rebinding *standard-output* like that library does, I guess. Because it'd be really inconvenient to have to pass in a stream to every BR
<vms14>
aeth: should be simple to let the user add tags and even change them
<vms14>
by providing access to a list where the tags lie
<vms14>
live*
<vms14>
there is a html generator library that does this?
<aeth>
vms14: you don't need to know about any tags to write HTML except for the empty elements like <br>
dale has quit [Quit: dale]
ggole has quit [Quit: Leaving]
<vms14>
yes you can put just <tag></tag> and don't know what the tag does or if exists
<aeth>
vms14: if you don't know that the tag exists, and if you do it in one big keyword macro instead of namespacing each tag in macros (or function calls or w/e) that have to know each tag... then, yes, if it's unknown it's just <tag>...</tag>
<vms14>
but if you're making a library for doing this, better if we provide access or a way to add tags
<vms14>
because macro-html provides some html5 tags, but isn't providing main
<vms14>
if you write a big macro then you need to provide a way to put stuff inside <tag > like :src "url"
<aeth>
vms14: that's easy
dale has joined #lisp
<aeth>
there are two syntaxes that work... (:tag :src "url" "foobar") and (:tag (:src "url") "foobar) where in the former case you iterate until you no longer get a keyword-and-value pair and that's the end of the attributes and in the latter case you always have an attributes list after every tag (more regular, but also means your code will probably be full of ()s)
<aeth>
s/"foobar)/"foobar")/
gravicappa has quit [Ping timeout: 250 seconds]
<aeth>
vms14: The reason you need to know about empty elements is because (1) they close like <foo> or <foo /> depending on the style and not <foo> </foo> and (2) you want there to be an error if there's a body and not just attributes
<aeth>
For all I know, in XML <foo /> and <foo> </foo> are interchangable, but HTML is not that kind.
<vms14>
then maintain one list with those tags
<aeth>
eh
<vms14>
so you can push stuff in this list
<aeth>
The lazy approach that you'd probably see in 95% of libraries that do this is to use a list.
<vms14>
the tags you need to care
<vms14>
how would you do it then?
<aeth>
What you should probably do, though, is you should probably use a member type, and for user configuration, also check a predicate function (perhaps an overridable method that by default turns nil? or maybe even just put it as a satisfies type)
<aeth>
vms14: so (or (typep foo 'empty-element) (custom-empty-element-p foo))
<aeth>
a higher order function could also work, but that makes the macro much messier if you need to override it so maybe just a method that always returns nil and letting the user do :after will be the best approach
mn3m has quit [Ping timeout: 246 seconds]
Arcaelyx has joined #lisp
nckx has quit [Quit: missing bootloader]
nckx has joined #lisp
ravenousmoose has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
scymtym has joined #lisp
gdsg has joined #lisp
Arcaelyx has quit [Quit: Arcaelyx]
<vms14>
it is good style to make a closure to have two or more functions sharing "local" variables
<vms14>
?
<vms14>
I have a *buffer* global variable but I have other functions that would need two different buffers
LiamH has quit [Quit: Leaving.]
<vms14>
should I change it locally, since it's special, or make a closure returning those functions, or what would be a good way?
rippa has quit [Quit: {#`%${%&`+'${`%&NO CARRIER]
<Xach>
vms14: need more context
varjag has quit [Quit: ERC (IRC client for Emacs 26.1)]
<vms14>
Xach yes, sorry. In my context I guess what I really need is local stuff inside a function
<vms14>
just (let stuff)
bleepcord has joined #lisp
EvW has quit [Ping timeout: 250 seconds]
moldybits has joined #lisp
ljavorsk has quit [Ping timeout: 240 seconds]
<aeth>
vms14: You can wrap a DEFUN in a LET, but that makes it no longer top level so macros that generate DEFUNs might not work properly (since those tend to assume they're at the top level, so they could do e.g. "(progn (declaim (inline foo)) (defun foo ..." since PROGN does keep functions at top level)
<aeth>
vms14: i.e. (let ((variable 42)) (defun foo () variable) (defun (setf foo) (value) (setf variable value))) (format t "~A~%" (foo)) (setf (foo) 1) (format t "~A~%" (foo)) ; prints 42 and then prints 1
<vms14>
I'm not thinking in macros
<vms14>
just a function that reads a list
<vms14>
with a typecase
<vms14>
would any function inherit a local variable in the calling context?
<aeth>
Are you asking if variable in my example would be accessible outside of those two functions? No, because it's lexically scoped and it's effectively creating a closure, just a global one, not one that you're used to seeing
<vms14>
(let ((oh 3))(function))
<vms14>
and function printing oh
<jasom>
vms14: that won't work unless oh is declared special (which seems unlikely given its name)
<aeth>
vms14: Lexical closures are afaik the only true way of encapsulation in CL (besides messing with symbols or the MOP or something)
<jasom>
vms14: lexical bindings affect only the code inside the let.
mindCrime has quit [Ping timeout: 250 seconds]
<aeth>
vms14: Your example oh will probably be optimized away into nothing since it's unused
<jasom>
vms14: I *think* you want something like (let ((*buffer* FOO)) (some-function)) (let ((*buffer* BAR)) (some-function)) but I may be misunderstanding your question; perhaps pastebin some code?
<aeth>
vms14: is (function) a call to FUNCTION or is it a shortcut for (defun function ...) in your notation?
<vms14>
but wasn't this related with "variable capture" in macros?
<vms14>
aeth: is a name of a defined function using *oh*
jmarciano has quit [Remote host closed the connection]
Arcaelyx has joined #lisp
<aeth>
vms14: the issue with macros is if you did `(let ((oh nil)) ...) in a macro. Then anyone who knows the variable "oh" could access it, and anyone who used the variable "oh" outside of the macro would unexpectedly get their variable overridden inside of the macro, so you gensym instead of directly binding a let, if you have a ,@body (you don't always make macros like that)
<aeth>
vms14: afaik, your question has nothing to do with that
<aeth>
vms14: The thing about *oh* is called dynamic scoping, and it's a separate thing. Basically, (let ((*oh* 42)) (foo)) will replace *oh* in (foo) and all of its callers with the local 42 instead of the global (whatever it is). So it's a separate, special scoping rule that's probably implemented as a stack or at least can be thought of as a stack.
<vms14>
so with recursion a function using let with a special variable and calling other functions that use this variable the function will preserve all the *stuff* values in a recursive way
<aeth>
vms14: I see what you're probably trying to do. You're probably trying to build up a list in a bunch of recursive calls, but you can't just pass in the list because push will only modify the local binding. So (push 42 *oh*) will keep building the list while (push 42 oh) will not. Is that correct?
<vms14>
aeth: sorry to share my code but this is what I'm doing
<aeth>
I love how that pastebin tries to get me to login to download the text. Easily the worse pastebin for that that I've seen. At least I can just copy and paste it into emacs.
<vms14>
I want to make :keywords process as tag attributes and symbols as tags
<vms14>
aeth: I use nopaste
<vms14>
is written in perl
<vms14>
cpan App::Nopaste
<jackdaniel>
I use a small shell script on top of scp
<vms14>
it's*
<vms14>
nopaste supports a lot of services
<jackdaniel>
i.e I call `hellpost foobar.lisp' from the command line
<vms14>
even github gists
<aeth>
vms14: I just did the exact same thing, actually
<vms14>
I have a function in emacs so I press C-c n and asks for a file
<aeth>
vms14: well, roughly the same thing
<vms14>
uses nopaste and writes in the buffer the link
<aeth>
vms14: you don't need to work with buffers at all, you can just work with streams and model it like a write function, e.g. (write-string "foo" some-stream)
<vms14>
yes my code sucks and the whole idea is wrong I guess
<aeth>
vms14: What I do is I write to a string stream at compile time, unless there's some special feature, and if there's a special feature, then I write (code char 0) and push that special feature to something that ultimately gets returned so that I can handle it elsewhere.
<aeth>
It's... kind of involved to do it efficiently, but not too hard to do it naively (since all that "unless there's..." can just be ignored)
<vms14>
my idea was to maintain two buffers, one for tag attributes and another for the output buffer
<aeth>
for output, just always pass in a stream argument and write to that stream. Technically, using a UTF-8 stream via babel would probably be more efficient than writing to a string that ultimately becomes UTF-8 at some later point, but efficiency isn't the most important thing if you just need to get it to run
<aeth>
I'm not sure why you need to track tag attributes at all?
<aeth>
you'll want '(img :src "url") or if in a macro just (img :src "url") because the macro will implicitly quote it and you'll want the whole thing quoted
<vms14>
I prefer (setf *print-case* :downcase)
<aeth>
Don't do that
<aeth>
that changes it for everyone forever
<aeth>
(let ((*print-case* :downcase)) ...) can work
<vms14>
ok
<aeth>
I mean, I normally do (setf *print-case* :downcase) in the REPL when I'm doing a lot of macroexpand so I can actually read the macros
<aeth>
I just can't assume that the user wants that or has that
<vms14>
I'd prefer if the repl does not scream me
<vms14>
so downcase would be nice to have as default
<vms14>
but yes, is a good advice to change it locally
<vms14>
I'll do it
<aeth>
vms14: You shouldn't be doing FORMAT *buffer*, though. You really want to only work with streams, and then when you call it, in the caller, do (with-output-to-string (output) (process-html-list list output))
<vms14>
I prefer to work with char arrays
<vms14>
format does work with fill pointer adjustable arrays
<aeth>
Even if buffer is more efficient for format, (1) being a special variable instead of a lexical variable is probably going to kill absolutely all of the efficiency gains (and it doesn't even know if it's a buffer or a stream or the symbol nil) and (2) it makes it much harder and less abstract for this particular problem
<aeth>
and plus (3) it's harder for this sort of problem
<aeth>
If you must do this, though, pass it in as an argument to everything
<vms14>
a keyword argument with a default value
ltriant has joined #lisp
<aeth>
You don't want a default value here because you're going to be using it for its side effect, recursively. If you want to add a default value, write a wrapper function where it's optional instead of making it be optional everywhere
<vms14>
I didn't know fill pointer adjustable arrays were faster than streams for format
<aeth>
You want to keep things as simple as possible. Nice to have features can be added later.
<aeth>
vms14: I don't know if they're faster or not.
<vms14>
are streams "faster" than arrays?
<Shinmera>
Phew, me and my two friends finished our Ludum Dare game jam entry just now! Three days to make a game, and of course we used lisp. https://ldjam.com/events/ludum-dare/45/outsider
<aeth>
vms14: Arrays can be faster, but if you wanted to really use arrays to their full potential you would have to do some really strange things. First, you'd have to give it a maximum size so there's no bounds checking. Second, you'd want to directly write UTF-8 bytes instead of characters to strings. Third, you'd have to use DECLARE on every function. This isn't really worth it unless you need the performance.
<vms14>
unless you improve my shit (make-text-buffer) function
<aeth>
And after all that I'm not sure it would actually be that much faster, since you'd have to use something like babel instead of the implementation's potentially very optimized character writer. It would use less memory, though
<vms14>
(defun make-text-buffer () (make-array 0 :adjustable t :fill-pointer t :element-type 'character))
doublex has joined #lisp
Bike has quit [Quit: Bike]
<aeth>
vms14: Anyway, as long as you only use FORMAT, your buffer code should be identical to stream-using code because there's no difference at all (unless you wanted to enforce your choice of using a buffer via a type check or type declaration)
<aeth>
Since the buffer goes into the stream spot
<aeth>
You might want to check that it's not NIL, though, since format nil will only work as expected on one FORMAT statement.
<aeth>
(although technically speaking you could do it in one format statement and use ~/foo/ to do your recursion, unless that's disallowed by FORMAT)
<aeth>
vms14: That basic form will give you something that will work with anything that format works with (except NIL as soon as you have more than one FORMAT, so maybe check for that and error) and if the user doesn't provide anything, then it just goes to *standard-output*, which can be rebound locally since it's a special (dynamic) variable
karlosz has joined #lisp
doublex_ has joined #lisp
<aeth>
vms14: The next thing that you should do is that you should change your syntax. (foo :bar 42 "Hello!") is actually really difficult and advanced because you have to parse it to know where the plist ends and the body begins. Try using (foo (:bar 42) "Hello!") instead. This syntax is regular. Then, if you come across a list you can parse it with destructuring-bind.
<aeth>
vms14: That syntax is then just (destructuring-bind (tag attribute-plist &body body) ...)
doublex has quit [Ping timeout: 268 seconds]
cbilt has joined #lisp
<aeth>
vms14: Then you can handle attributes as their own special case and call them with (process-html-attributes list format-destination) without having to worry about process-html-list having to know at all about attributes
cbilt has left #lisp [#lisp]
<aeth>
vms14: If you want to have tiny little functions for everything in parse-html-list, you can use FLET and put them at the top of PROCESS-HTML-LIST and then you don't have to pass format-destination and you don't have to make a global *buffer* because it's creating a closure. So (flet ((start-tag (tag) (format format-destination "<~a" tag)) ...
<vms14>
I always wanted something like (title :color red "hi")
<vms14>
that writes to <head> a <title>hi</title> tag and also a <h1>hi</h1> in body
<vms14>
the problem is mixing css while not wanting to put dirty inline styles
<vms14>
so for :color red I should have a class .red and create it if not exists
<vms14>
and put a class="red" in this tag
<aeth>
vms14: That's the wrong thing to think about at this point. At this point you want a direct representation of HTML in s-expressions translated directly to an HTML string (or character buffer)
longshi has quit [Ping timeout: 246 seconds]
<aeth>
vms14: Once it's in s-expressions, you can preprocess it using list processing stuff later on as an earlier stage in your generation
<vms14>
aeth: yes, this is what really made me stop
<vms14>
I shouldn't care about this and just use inline style
<aeth>
vms14: the only thing special I do is insert "<!DOCTYPE html>" in front of "<html>" when that tag comes up because it's kind of important not to leave out
<aeth>
everything else can be added by another stage
<vms14>
but the right thing I think is to have classes
<aeth>
vms14: You are writing a function that writes HTML strings when given HTML in s-expression form, so that's all it should do (I kind of break this rule myself to allow support for some very simple things, but that's mainly because I couldn't find a better way to do it)
<aeth>
vms14: So you shouldn't be thinking about "so for :color red I should have a class .red and create it if not exists"
<aeth>
That can be done in another pass, before you pass the list to the writer
<vms14>
well, the end goal would be to even put js
bleepcord has quit [Quit: WeeChat 2.6]
<vms14>
I'd want to have a lisp language for the web
<aeth>
vms14: Yes, but you will probably never finish if you make your functions do too many things at once... if you make them too smart.
<vms14>
it needs to transpile css js and html
<vms14>
but lisp could represent css and html in a better way than those "languages" do
<vms14>
not me, but a lisper could
<aeth>
vms14: JS is much harder than the rest, and isn't really critical for the basic task, so you should ignore that for now. And when you do write JS, you should write JS in a direct s-expression representation of JS, rather than trying to do anything fancy, because it's much easier to do fancy things as s-expression->s-expression
<Ober>
thanks jmechier
<aeth>
vms14: Anyway, no matter how much you hate the source language and think that it can be improved upon, you can't do that in the function that calls FORMAT because then you'll add too much logic by the time you're done. What you'll want to eventually do is (generate-html (c (b (a your-awesome-language))) buffer)
<aeth>
You're essentially doing a multi-pass compiler
gxt has quit [Ping timeout: 260 seconds]
<vms14>
the problem is the only way to have a lisp language instead of html+css is making a transpiler
<vms14>
I think sexp would be better than both
<aeth>
vms14: Yes, but you were looking at the s-expression problem incorrectly. If you use the syntax (foo (:bar 42) "Hello!") then there are only two cases at the top level. Either it is a list or it is not a list. If it is not a list, then it's in the body and should be an escaped string (to escape stuff like <). If it is in a list, then it has the regular structure (destructuring-bind (tag attribute-plist &body body) item ...)
<aeth>
and in the later case, you recursively call on every item in body
cosimone has joined #lisp
<aeth>
In all recursive calls, pass format-destination even though you want to make it a keyword argument and optional for the caller. Then, you don't need *buffer* as a global, since buffer is passed each time
<vms14>
then how would be your syntax for a lisp language like (title "hi" :color "red" :onclick #'dosomething)
<aeth>
vms14: That's a separate problem. There, you turn (title "hi" :color "red" :onclick #'dosomething) into (title (:color "red" :onclick "dosomething()") "hi") which is regular and simple and known, and can then be written by the writing function that I described
<aeth>
or whatever it takes to make it valid HTML
<aeth>
you would probably have to parse a mini-language, like the LOOP macro
<vms14>
yes. it's much easier to handle with a list for optional "attributes"
<aeth>
vms14: you don't even need to do the writing function if what you really want to do is the fancy part, since the writing function has been done a dozen times before (sometimes with the syntax (:foo :key "value" "body1" "body2") and sometimes with the syntax (:foo (:key "value") "body1" "body2") and sometimes with other syntax, but none of that matters if you're processing it anyway)
<aeth>
the writing part isn't as easy as it seems because you have to escape <, >, and &, and if in an attribute you also have to escape "
<aeth>
Some of them might escape more just because, or even make it configurable
red-dot has quit [Quit: Going offline, see ya! (www.adiirc.com)]
leb has joined #lisp
karlosz has quit [Quit: karlosz]
Bike has joined #lisp
raghavgururajan has joined #lisp
gdsg has quit [Remote host closed the connection]
Arcaelyx has quit [Quit: Arcaelyx]
<thijso>
Shinmera: looks interesting, but it's way past my bedtime here. I'll try to remember to look at it tomorrow. Or remind me...
Josh_2 has quit [Read error: Connection reset by peer]
cosimone has quit [Quit: Terminated!]
EvW1 has joined #lisp
leb has quit []
hiroaki_ has quit [Ping timeout: 240 seconds]
ebrasca has quit [Remote host closed the connection]
hh47 has joined #lisp
<no-defun-allowed>
w.r.t update-instance-for-redefined-class, if I redefine a class A to A', then A' to A'', does the function have to be called twice or can the function "jump" from A to A''?
gabiruh has quit [Remote host closed the connection]
nowhere_man has joined #lisp
<Bike>
it could jump
<Bike>
the object isn't necessarily updated as soon as you redefine the class
<Bike>
"Updating such an instance occurs at an implementation-dependent time, but no later than the next time a slot of that instance is read or written."
<no-defun-allowed>
Thankyou.
<Bike>
so if you don't access a slot while it's an A', no update
<Bike>
not necessarily an update, rather
akoana has joined #lisp
vms14 has quit [Remote host closed the connection]
moldybits has quit [Quit: WeeChat 2.4]
nowhere_man has quit [Ping timeout: 276 seconds]
smazga has quit [Quit: leaving]
quazimodo has joined #lisp
sjl has quit [Quit: WeeChat 2.2-dev]
X-Scale has quit [Ping timeout: 240 seconds]
X-Scale` has joined #lisp
X-Scale` is now known as X-Scale
leb has joined #lisp
EvW1 has quit [Ping timeout: 276 seconds]
Josh_2 has joined #lisp
<no-defun-allowed>
Is it possible to write a file before closing it?
<no-defun-allowed>
Maybe that's finish-output.
<Josh_2>
terpri?
<Josh_2>
finish-output works
ralt has quit [Quit: Connection closed for inactivity]