That's true but with comments ;) Composing strings (packing) have two main advantages:
1. Strings may be inmutable (you can return a new different string, maybe a copy) 2. Strings can be passed as parameter The fexpr writing directly to stdout with print and running a program does not returns a string with the intended result: : (de <p> P (prin "<p>") (run P) (prin "</p>")) -> <p> : (<p> hallo) <p></p>-> "</p>" : (length (<p> hallo)) <p></p>-> 4 : (setq X (<p> hallo)) <p></p>-> "</p>" : X -> "</p>" You can argue return value is nothing you must worry about because you're only going to print the result, so better use it as a side effect. But this is not always true, returning a string you can further compose it and make transformations to it So first problem with this fexpr (programmed this way) you don't have the intended return value and thus you cannot use it as parameters to other function invocation Second problem is about inmutability, as you don't return the value you cannot have a completely different memory object. Ovbiously you can arrange the program (P) you pass to the fexpr and get those problems solved by example packing into the result but it may become not easy to write the function due to side effects: : (de pp P (prin "<p>") (run P) (prin "</p>") (pack "<p>" (run P) "</p>") ) : (pp (+ 2 3)) <p></p>-> "<p>5</p>" : (pp 2) <p></p>-> "<p>2</p>" : (pp (print 2)) <p>2</p>2-> "<p>2</p>" : (pp (<p> (prin "hallo"))) <p><p>hallo</p></p><p>hallo</p>-> "<p></p></p>" : (pp (pp (prin "hallo"))) <p><p>hallo</p>hallo</p><p>hallo</p>hallo-> "<p><p>hallo</p></p>" : (<p> (<p> (print "hallo"))) <p><p>"hallo"</p></p>-> "</p>" so you must code carefully the fexpr, and anyway if you're going to return a string then side effects are often innecesary. More interesting is last use of fexpr which is the true reason of existence of fexpr's, being able to write macros But even when being needed as the only way to write certain functions (aka macros), most of the time are not needing, like the intended use with <div> showed as an example by Alex. Given: : (de p (t) (pack "<p>" t "</p>")) : (de d (c t) (pack "<div class=\"" c "\">" t "</div>")) the example given by Alex to get a multiline div is simply this one-liner: : (prinl (d "red" (glue "^J" (mapcar p '("ABC" "DEF" "GHI"))))) <div class="red"><p>ABC</p> <p>DEF</p> <p>GHI</p></div> El sáb., 13 mar. 2021 8:32, Alexander Burger <a...@software-lab.de> escribió: > Hi all, > > at PilCon three days ago we discussed about FEXPRs like > > (de <p> Prg > (prin "<p>") > (run Prg) > (prin "</p>") ) > > (de <div> (Col . Prg) > (prin "<div class=\"" Col "\">") > (run Prg) > (prin "</div>") ) > > which can be called as > > (<div> "red" (<p> (prin "Text"))) > > giving such output: > > <div class="red"><p>Text</p></div> > > > One question that came up was why FEXPRs could not be replaced with normal > functions (EXPRs), simply 'pack'ing strings: > > (de <p> (Str) > (pack "<p>" Str "</p>") ) > > (de <div> (Col Str) > (pack > "<div class=\"" > Col > "\">" > Str > "</div>" ) ) > > : (<div> "red" (<p> "Text")) > -> "<div class=\"red\"><p>Text</p></div>" > > While this would surely work, I answered that it is a big overhead to > generate > the whole page as strings just to print them. > > > But I forgot to explain: The real reason for FEXPRs goes beyond that. They > have > the power of passing executable code bodies, with arbitrary flow control, > to the > function. > > To pick just a minimal example: > > (<div> "red" > (for S '("ABC" "DEF" "GHI") > (prinl) > (<p> (prin S)) ) > (prinl) ) > > <div class="red"> > <p>ABC</p> > <p>DEF</p> > <p>GHI</p> > </div> > > This cannot be done with EXPRs. > > ☺/ A!ex > > -- > UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe > >