Hi. I'm sortof new to LISP, so I'm not that good at it, but i wrote a program that converts decimal numbers into Roman numerals. It's not that exciting of a programming, but I like making unique little programs that I can use at the oddest times. LISP is an awesome language, but I think it's harder to read (i made a game in C before this so i'm a C programmer). I decided to use the C style to make the code look more organized. I think it makes it easier to read. It's not GNU style, but I was wondering if the GNU has a format guideline for LISP. I was thinking of submitting something like this, because it makes LISP code easier to read.
(
defun roman1
(
)
"Roman numeral conversion with an unordered P.S."
(
let
(
(
x nil
)
)
(
loop
(
cond
(
(
null x
)
(
format t "Enter number:"
)
(
setf x
(
read
)
)
)
(
(
and
(
not
(
null x
)
)
(
> x 39
)
)
(
format t "too big~%"
)
(
setf x nil
)
)
(
(
and
(
not
(
null x
)
)
(
< x 40
)
(
> x 9
)
)
(
prin1 'x
)
(
setf x
(
- x 10
)
)
)
(
(
and
(
not
(
null x
)
)
(
= x 9
)
)
(
prin1 'ix
)
(
setf x 0
)
)
(
(
and
(
not
(
null x
)
)
(
< x 9
)
(
> x 4
)
)
(
prin1 'v
)
(
setf x
(
- x 5
)
)
)
(
(
and
(
not
(
null x
)
)
(
= x 4
)
)
(
prin1 'iv
)
(
setf x 0
)
)
(
(
and
(
not
(
null x
)
)
(
< x 4
)
(
> x 0
)
)
(
prin1 'i
)
(
setf x
(
1- x
)
)
)
(
(
zerop x
)
(
setf x nil
)
(
terpri
)
)
)
)
)
)
Name:
Anonymous2009-11-03 1:55
Whoops, my IDE has a custom setup so it looks weird on 4chan. Let me try this:
(
defun roman1
(
)
"Roman numeral conversion with an unordered P.S."
(
let
(
(
x nil
)
)
(
loop
(
cond
(
(
null x
)
(
format t "Enter number:"
)
(
setf x
(
read
)
)
)
(
(
and
(
not
(
null x
)
)
(
> x 39
)
)
(
format t "too big~%"
)
(
setf x nil
)
)
(
(
and
(
not
(
null x
)
)
(
< x 40
)
(
> x 9
)
)
(
prin1 'x
)
(
setf x
(
- x 10
)
)
)
(
(
and
(
not
(
null x
)
)
(
= x 9
)
)
(
prin1 'ix
)
(
setf x 0
)
)
(
(
and
(
not
(
null x
)
)
(
< x 9
)
(
> x 4
)
)
(
prin1 'v
)
(
setf x
(
- x 5
)
)
)
(
(
and
(
not
(
null x
)
)
(
= x 4
)
)
(
prin1 'iv
)
(
setf x 0
)
)
(
(
and
(
not
(
null x
)
)
(
< x 4
)
(
> x 0
)
)
(
prin1 'i
)
(
setf x
(
1- x
)
)
)
(
(
zerop x
)
(
setf x nil
)
(
terpri
)
)
)
)
)
)
Please don't look at the other 2. I'm from /g/ so I don't know text boards format that much (i only know bbcode. is there another way to do it? the code tag is messing it up i think).
(
defun roman1
(
)
"Roman numeral conversion with an unordered P.S."
(
let
(
(
x nil
)
)
(
loop
(
cond
(
(
null x
)
(
format t "Enter number:"
)
(
setf x
(
read
)
)
)
(
(
and
(
not
(
null x
)
)
(
> x 39
)
)
(
format t "too big~%"
)
(
setf x nil
)
)
(
(
and
(
not
(
null x
)
)
(
< x 40
)
(
> x 9
)
)
(
prin1 'x
)
(
setf x
(
- x 10
)
)
)
(
(
and
(
not
(
null x
)
)
(
= x 9
)
)
(
prin1 'ix
)
(
setf x 0
)
)
(
(
and
(
not
(
null x
)
)
(
< x 9
)
(
> x 4
)
)
(
prin1 'v
)
(
setf x
(
- x 5
)
)
)
(
(
and
(
not
(
null x
)
)
(
= x 4
)
)
(
prin1 'iv
)
(
setf x 0
)
)
(
(
and
(
not
(
null x
)
)
(
< x 4
)
(
> x 0
)
)
(
prin1 'i
)
(
setf x
(
1- x
)
)
)
(
(
zerop x
)
(
setf x nil
)
(
terpri
)
)
)
)
)
)
Name:
Anonymous2009-11-03 2:08
>3
Why zero points?
Also, I got it working 8-)
Name:
Anonymous2009-11-03 2:08
This really drives home how retarded and unreadable C-style formatting is.
Your indentation/formatting style is non-idiomatic. Please read http://dept-info.labri.fr/~strandh/Teaching/MTP/Common/Strandh-Tutorial/indentation.html for indentation, and http://mumble.net/~campbell/scheme/style.txt (Scheme specific, but still important). Get a good editor like Emacs, SLIME for interaction with your Lisp and Paredit for structured editing. You do get plenty of freedom on how you split lines, but the actual formatting is shared between most Lisp programmers, because people don't read code by counting parens, but they read it by indentation and general positioning of your code.
Here's your code reformatted using Emacs:
(defun roman1 ()
"Roman numeral conversion with an unordered P.S."
(let ((x nil))
(loop
(cond
((null x)
(format t "Enter number:")
(setf x (read)))
((and (not (null x))
(> x 39))
(format t "too big~%")
(setf x nil))
((and (not (null x))
(< x 40)
(> x 9))
(prin1 'x)
(setf x (- x 10)))
((and
(not
(null x))
(= x 9))
(prin1 'ix)
(setf x 0))
((and (not (null x))
(< x 9)
(> x 4))
(prin1 'v)
(setf x (- x 5)))
((and (not (null x))
(= x 4))
(prin1 'iv)
(setf x 0))
((and (not (null x))
(< x 4)
(> x 0))
(prin1 'i)
(setf x (1- x)))
((zerop x)
(setf x nil)
(terpri))))))
Your code is not very idiomatic as well, and shows that you probably did not study Lisp from a good book (or didn't finish reading the book).
Here's some pointers:
Practical Common Lisp (freely available) or ANSI CL, and look
up the functions in the Hyperspec. http://norvig.com/luv-slides.ps for general Lisp coding style questions.
Here's my attempt at solving your problem:
;;;; Some common utils
(defun flip (x)
(destructuring-bind (a b) x (list b a)))
(defun flatten (tree)
"Traverses the tree in order, collecting non-null leaves into a list."
(let (list)
(labels ((traverse (subtree)
(when subtree
(if (consp subtree)
(progn
(traverse (car subtree))
(traverse (cdr subtree)))
(push subtree list)))))
(traverse tree))
(nreverse list)))
(defun single-integer->roman (x)
(assoc x '#.(mapcar #'flip *roman-numerals-table*)
:test #'(lambda (x element)
(>= x element))))
(defun integer->roman-numeral-list (x)
(flatten
(loop
for i = (single-integer->roman x)
while i
for (value roman-numeral) = i
collect roman-numeral
do (decf x value))))
(defun integer->roman-numeral-string (x)
(check-type x integer)
(concatenate 'string (integer->roman-numeral-list x)))
;;; I don't write main functions too often, instead just use the REPL, but since you wrote one, here it is:
(defun main ()
(loop
(format t "Enter number:")
;; Don't let the user execute code through user input
(let (*read-eval*)
(let ((x (read)))
(if x
(format t "~&~A~&" (integer->roman-numeral-string x))
;; User entered 0, we're done
(return nil))))))
I believe my code is more idiomatic Lisp, and it's more extensible than yours. You could for example, easily add support for multiples of 1000 in it, just by modifying *roman-numerals-table* to contain what is needed. Note that if you do so, you must redefine or recompile single-integer->roman as it caches the values.
>>14
It's true for other languages too. People would have trouble reading badly formatted C code too. The actual formatting used in Lisp programs is liberal, but you should use an editor which indents the code for you, so you and other people could read it. The formatting isn't forced in most languages, however it's needed if you want to be able to read the code fast.
Name:
Anonymous2009-11-03 15:56
Welcome to the world of LISP troll-chan. Where everything that could be explored about the language has been explored and decided long before you were born. Where the moment you fail to live up to those long established "standards" (there is really very little that is standard about it) you are never congratulated for picking up an archaic and impractical language, or encouraged to play around further even if imperfect, but instead directed to tombs written ages ago by people who had long lost any excitement in their lives.
>>16
There are very good reasons for these 'standards'. You can choose to ignore them and reinvent the wheel, but you should know that the chances of you inventing something better without knowing what your predecessors knew are slim.
In fact, there's many people who reinvented Lisp. Few have done better than Scheme or Common Lisp.
Name:
Anonymous2009-11-03 16:09
OP here. I don't get it. Are you guys saying this is good or bad? have you guys ever programmed in C? I think its a lot easier to read for a C programming because it is layed out in C style. Sometimes when I read other people's LISP programs they have 10 statements on one line. its like trying to read:
I knwo there are other standards, but what Im saying is mine is better.
Name:
Anonymous2009-11-03 16:09
This may be the worst abuse of parentheses in a programming language ever (class Set of List
(properties
elements 0
size 0
)
(method (showStr strBuf)
Format(strBuf "%s\n[Set of size %d]" objectName size)
)
(method (add nodes)
(var i, hNode)
(if(not elements)
= elements NewList()
)
(for (= i 0) (< i paramTotal) (++i)
= hNode nodes[i]
(if(not (self:contains(hNode)))
AddToEnd(elements NewNode(hNode hNode))
++size
)
)
)
)
>>14
You can't really call them "people" more like "Guido's babies", and they will continue to be so, until they break out of the Guido is always right mentality
Name:
Anonymous2009-11-03 16:11
Also I think LISP is an awesome language, but I think real programmers have to know C, so only respond if youve made something big in C (like a game [i have]). LISP people can respond too, but make sure you tell us you dont know C.
>>19,22
Are you OP?
I learned C and x86 asm long before I learned Lisp. I think I know the languages decently.
Lisp is not C. Don't think of it as a replacement for C.
C has its place and own rules.
Lisp has its place and own rules.
You should not code Lisp like it would be C.
First, get a good Lisp book and read it cover-to-cover, while interactively working in Emacs+SLIME+Paredit, then come and ask questions.
If you just learn Lisp's simple syntax and a few simple operators, and write in C style, then Lisp won't do you much good. Instead, if you learn Lisp as its own language properly, it would be a much more useful tool to you.
Name:
Anonymous2009-11-03 16:19
>>24
I don't use it as C, i just make them look the same. I already read tutorial online about how to program LISP, and I understand you use LISP for lists (its a list processor). I just think that people who write LISP write it really condensed and makes it harder to read. C is a really popular language because it has a smart way to write it so everyone can read C code.
>>25
What tutorial did you read? Your use of Lisp shows that you don't know the language too well, there's quite a few better ways to do the task, and more suitable operators for some of the things you typed.
Do you honestly think the way you're indenting it, is easier to read? Oh, and as a 'list processor', you're not really using any lists in your code. Chances are, your code is actually faster than mine (>>12), but less flexible (can only convert 1-39).
My personal experience with Lisp indentation:
The first few days when I started learning the language, it was a bit hard to get used to, but after half a week, I was able to read it fluently, and I prefer it to non-standard indentation styles like yours. I can't read your code at all without reformatting it, it's just plain unreadable to me. You don't need to learn how to indent Lisp code, Emacs and other Lisp editors do it for you. If you refuse to learn to do it, it would:
1)Make you unable to read other people's code, which means: no reading your Lisp's implementation source code or libraries or code by other people, not even code in books. This limits your sources for learning the language a lot, as well as capability to interoperate with other's code.
2)It would slow down the pace at which you write code.
Name:
Anonymous2009-11-03 16:52
>>23
A scripting language for a game engine. I have no idea what made this person think that using parens for both delimiting blocks and calling functions is a good idea.
Name:
Anonymous2009-11-03 17:16
>>25
Sure, because adding useless whitespace and line breaks everywhere makes code easier to read, rather than just making it harder to see it all at once.
its a list processor
Yes, let's ignore all the other data types list has to offer, vectors and hash-tables for start C is a really popular language because it has a smart way to write it so everyone can read C code.
4/10 I lol'd
Everyone can read C, because the majority of the popular languages (for teaching and in the enterprise) share the same syntax.
Let's not forget the 30+ years of fucking formatting arguments K&R vs Allman vs Gnu (not really ;) vs VIP-STYLE
Name:
Anonymous2009-11-03 17:38
>>27
I don't use a lot of others people code. Usually they don't write it well, so I spend my time writing a good version that i know is fast and will work. As a point, you already said my code is faster than yours. Also, I don't use an IDE write code for me. I use an IDE to write my code in. THis is something noobie programmers do with C# and Java.
>>28
Scripting languages aren't good for game engines. They are slower than compiled code and games need to be really fast to keep their FPS.
>>29
You don't read code all at once, you read it sequentally. This format lets you read it more easily and doesn't effect how much you read, because you read sequentally anyways.
[quote]Everyone can read C, because the majority of the popular languages (for teaching and in the enterprise) share the same syntax.[/quote]
This is because C ahs good formatting so everyone uses it.
fubar(y, x, z)
register short *y, *x;
register z;
{
register n=(z+7)/8;
switch(z%8){
case 0: do{ *y = *x++;
case 7: *y = *x++;
case 6: *y = *x++;
case 5: *y = *x++;
case 4: *y = *x++;
case 3: *y = *x++;
case 2: *y = *x++;
case 1: *y = *x++;
}while(--n>0);
}
}
everyone can read C code, eh?
Name:
Anonymous2009-11-03 17:44
>>33
What's the name of that "pattern"? I've seen it before, but I can never remember
Name:
Anonymous2009-11-03 17:45
I HATE women. I never had a girlfriend and never will. The only times I got laid was when I paid a woman or promised her something. I'm never going to hold hands with a chick, kiss a girl intimately because we're in love, or any of the other shit that human beings were made to do. I guess that I'm suppose to be happy masturbating every fucking night. I'm a man with sexual urges and can't get with a female. I'm suppose to be alright with that? THERE IS A FUCKING CURSE ON MY LIFE. A CURSE THAT PREVENTS ANY FEMALE FROM LIKING ME. Oh I forgot, I do get interest from fat chicks and I'm not attracted to fat chicks.
I don't give a fuck anymore. I'm going to become the biggest asshole in the world. I tried the whole being considerate thing and it got me nowhere. If people can't handle my newfound harshness, then bring it on. BECAUSE I DON'T GIVE A FUCK. I DON'T GIVE A FUCK. I DON'T GIVE A FUCK.
I get happy when I hear about some college slut getting murdered or injured in a hit and run. "oh she was a beautiful and talented girl, how could this happen." I don't know but I'm glad it did.
>>31
My code is slower since it's supposed to handle a much wider range of values than yours, and is much more extensible. I could write something as fast, but it will take more lines to keep it as extensible. Also, I don't use an IDE write code for me. I use an IDE to write my code in.
If you don't use something to help you write code faster, then you'll just spend your time writing that code (and whitespace) by hand. Guess which is smarter?
You also sound awfully similar to someone else on /prog/. I believe you and FrozenVoid would make good friends.
Name:
Anonymous2009-11-03 17:47
>>34 Duff's device
and it's what real men call DESIGN PATTERNS
>>37
from the wiki This modified form of the Device appears as a "what does this code do?" exercise in Bjarne Stroustrup's book The C++ Programming Language, presumably because novice programmers cannot be expected to know about memory-mapped output registers.
This made me a little sad, knowing that it's true for far too many professional programmers these days
>>37
You don't really need it on x86, and on other platforms. memcpy is supposed to be as fast. An optimized buffer copy on x86 is like:
void *memcpy( void *dest, const void *src, size_t count )
{
__asm
{
mov esi, src
mov edi, dst
mov edx, count ; in bytes
mov ecx, edx
shr ecx, 2 ; ecx is now amount of dwords (size/4)
rep movsd ; copy (size/4) dwords == (size/4)*4
mov ecx, edx
and ecx, 4 ; ecx is now amount of bytes left (size%4)
rep movsb ; copy remaining bytes
mov eax, edi ; return output buffer
}
}
Note that I just wrote this from memory, so I haven't tested if it compiles. Note that smarter compilers will inline this, and may remove the last part if the size is divisible by 4. Many compilers on the x86 perform such optimizations, and not only for C compilers.
>>31 Scripting languages aren't good for game engines. They are slower than compiled code and games need to be really fast to keep their FPS.
FrozenVoid detected. saging for teenage poster.
>>45
Never said my way was the most optimized one. My memcpy version assumes at least a 386 x86 CPU. Newer CPUs can use some MMX/SSE copy instructions instead, and 64bit CPUs would benefit from using larger registers.
Name:
Anonymous2009-11-03 21:01
I actually think this looks better than most Lisp programs. I would recommend not going as far as you did, and revert parts like this:
(
(
stuff
)
(
stuff
)
)
into
(
(stuff)
(stuff)
)
Also, I wouldn't try to get this format standardized by the GNU. They are into batshit standards, as you probably know from their C standard. They probably loved how fucked up most Lisp programs look.
Name:
Anonymous2009-11-03 22:28
>>31 You don't read code all at once, you read it sequentally.
Oh look, a slow reader. Maybe one day you'll learn to read fluently.
Name:
Anonymous2009-11-03 22:33
>>19 OP here. I don't get it. Are you guys saying this is good or bad? have you guys ever programmed in C? I think its a lot easier to read for a C programming because it is layed out in C style. Sometimes when I read other people's LISP programs they have 10 statements on one line. its like trying to read:
I knwo there are other standards, but what Im saying is mine is better.
I find the Lisp code easier to read than that C code (which isn't even correct, look at the syntax for the while loop in your example is wrong - I'm assuming while(true) or while(x > 20) && (x < 40)):
(loop
(cond
((< 20 x 40) (princ "a") (incf x))
(t (return 0))))
(loop
(if (and (< 20 x)
(< x 40))
(progn (format t "a") (incf x))
0))
(let ((x 21))
(loop while (< 20 x 40)
do (progn (format t "a") (incf x)))
0)
You also stated that you're forced to put everything on the same line, which is just wrong, because if you had a good editor like Emacs, formatting something like: (+ (* 5 6) (/ 9 8) (- 10 (+ 11 12 13 (1- 16))))
into something more readable, like:
(+
(* 5 6)
(/ 9 8)
(- 10
(+ 11 12
13 (1- 16))))
can be done only with a few key presses: moving the cursor around, and pressing enter, that's all.
Oops, fixed indentation(Shiichan formats tabs differently) and one statement.
(loop
(if (and (< 20 x)
(< x 40))
(progn (format t "a") (incf x))
(return 0)))
Name:
Anonymous2009-11-03 23:39
>>47
Thanks, I'm glad you agree with me. I will try that style in the next code I write. I was thinking about making a LISP program that does matrix multiplication so I can use it when I try to make a 3D game!
>>49
Ugh, I guess I can never show LISP users how much easier C is to read. I give up. I also said I don't let the IDE write my code. That is what newbies do and they cant even read there own code afterwards.
Name:
Anonymous2009-11-04 0:07
they cant even read there own code afterwards.
What about they are own code?
Ugh, I guess I can never show LISP users how much easier C is to read
That's because it isn't, duh. Lisp and C are fundamentally different beasts and expecting to be able to write them in exactly the same way is, at best, folly and at worst, a crime against your fellow programmer. That's like suggesting we take a Haskell program and write it out as a C program Oh wait, Haskell caved with it's do syntax, although even that is better than standard C
Name:
Anonymous2009-11-04 0:30
>>53
No, Haskell is a modern language that is well thought out and knows that C has a good format. LISP came before and doesn't evolve.
Name:
Anonymous2009-11-04 0:33
>>52
Yes, I used the wrong "there", but that's not the write one either. They're means "they are", it should be their.
>>57
LISP isn't a bad language, but I agree with you that a lot of the LISP users here are "weenies". I guess I can try another LISP place, people here probably aren't even as good at LISP as I am. That one guy couldn't even write as fast of a program as me.
>>56
Both languages' specifications are littered with implementation specific behaviours. This goes for ANSI C, and it surely goes for ANSI CL(just look at the Hyperspec). This isn't anything bad about that, as some liberty is required in real languages about how certain platform specific things are implemented, and in the case of CL, they left certain things open as there were multiple Lisp implementations/languages which did things differently and their goal was to unify the language while making it not too hard for them to turn their implementations into a Common Lisp. I think they did a very good job, even though some parts could have been more specific.
>>1,54 implying Lisp' evolution is changing the indentation style
Nothing stops you from your silly quest, just don't expect many people to follow you on this path.
Name:
Anonymous2009-11-04 1:18
>>63
If I get it standardized then a lot of people will. Thats why I am thinking about submitting it to GNU
Name:
Anonymous2009-11-04 1:20
>>64
Nobody uses GNU indentation stye for anything.
>>64
And what makes you think that people will not just continue on with their own preferred, widely accepted and well rationalized indentation style just because you manage to convince some halfwit at the GNU project?
>>69
The linux kernel has it's own coding guidelines, which are separate from GNU's. Which is why on a default emacs you have to use C-c C-. linux to use their coding style
>>64
I don't think GNU would accept it. GNU's Emacs Lisp indentation style is similar to the Common Lisp style, but is older, and has some minor differences about indenting a few forms.
You should understand that the indentation style is a shared culture among Lisp programmers, and is fairly important, so important that few people would bother reading incorrectly indented code. rms is more conservative than most Lispers, I have doubts he would not completly ignore your mail. Not only that, but almost nobody except some really green newbies would consider writing in a different indentation style, and that is because they haven't used a good editor capable of indenting Lisp code automatically or they're just plain stubborn fools. How many days did you say you studied Lisp for, and what books have you read on the subject?