Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Pascal vs C

Name: Anonymous 2010-04-05 17:12

If you were to give a language like Python static typing and make it a compiled language instead of interpreted, you basically end up with something like Pascal. So how would you rate Pascal's abilities compared to C? I know dynamic typing requires runtime checking, but would it be possible to have dynamic typing in a compiled language like Pascal?

Name: Anonymous 2010-04-05 17:54

I'm going to ignore the last sentence, because it makes no sense in context.

Pointers in Pascal are abysmal. It feels like wearing gardening gloves when writing Pascal.
C, on the other hand, is versatile (so much so that C++ is just syntactic sugar if you know C well enough) and feels like you have the hands of Mozart flowing across flowing across your keyboard.

Name: Anonymous 2010-04-05 18:28

I'm going to ignore the last sentence, because it makes no sense in context.

Why does it make no sense? Ive noticed that most dynamic languages like Python, Perl, Ruby dont seem to be able to compile to machine code well, so Im guessing there is something inherently non-machine compilable about dynamic languages

Name: Anonymous 2010-04-05 18:31

I feel violated by this thread.

Name: Anonymous 2010-04-05 18:45

Yes, just use the dynamic assembly type.

Name: Anonymous 2010-04-05 19:11

>>3
Dynamic typing is not an assembly-level feature, so there's a considerable runtime support requirement. Same goes for GC though.

Name: Anonymous 2010-04-05 19:17

OP go learn what a JIT is, and then tell me if dynamic languages are inherently slow.

Name: Anonymous 2010-04-05 19:30

>>3
[b]LAINSICP is dynamic and compiled.

Name: Anonymous 2010-04-05 19:58

>>8

Nice BBCode there, Anonymous.

Name: Anonymous 2010-04-05 20:36

>>7
Yes, they are.  P.S. Go read about reality.

Name: Anonymous 2010-04-05 21:00

>>10
Listen here, jerkface.

Name: Anonymous 2010-04-05 21:20

>>8
Yeah, to LISP machine. There are better examples.

Name: Anonymous 2010-04-06 3:33

>>12
What the fuck did you mean to say? That doesn't even make sense.

Name: Anonymous 2010-04-06 4:52

>>13
He's saying that Lisp is compiled to LISP machine. He's saying this because he is a dumb.

Name: Anonymous 2010-04-06 6:04

Common Lisp compiles quite nicely to native code (such as x86). Go look at SBCL, CCL, ACL, SCL, LW, XCL, ... I actually have trouble thinking of what doesn't have some native code support, even CLISP which is one of the slowest/interpreted has a JIT, so it's not entirely interpreted.

CL is fully dynamically typed, and can compile code at runtime. You can however, give hints to the compiler about something's type and if the compiler is good, it may be able to store something unboxed/without tag bigs/no runtime checks or in a more efficient manner.

Full-on dynamic typing is inherently slower than static typing because you have to check if types/functions compatible, and the compiler will generate typechecking code for you(you can do it manually too). Of course, if the compiler can infer types, some safe optimizations are possible. SBCL can to some degree, but Lisp is a very dynamic language, which makes things like ML's or Haskell's typechecking system incompatible with the language design. A subset can be compatible, but you can't gurantee the ``correctness'' of a program at compile-time. Think about functions which can take arguments functions and other arguments of unknown types then call the functions with those arguments (like APPLY/MULTIPLE-VALUE-CALL/FUNCALL/...) or CLOS which allows you to add methods or redefine classes at runtime. I think CL strikes a good balance between dynamic typing and leaving things open to optimization, but it's still not perfect.

Name: Anonymous 2010-04-06 9:02

>>15
Yes it does. And it has a big fat runtime to deal with the fact that the underlying machine isn't LISP. (It could be worse, but the point is an assembly language with dynamic typing doesn't need much runtime support.)

Name: Anonymous 2010-04-06 9:49

>>16
And it has a big fat runtime to deal with the fact that the underlying machine isn't LISP.
That's not true.

Name: Anonymous 2010-04-06 12:49

>>16
There's lisps with fairly tiny runtimes, and some with bigger runtimes(1-2MB on the smaller ones, up to 40MB on the larger ones). You should look into what is contained in those runtimes before you say they're big - they tend to contain a lot of things(such as the entire compiler/implementation, many useful libraries and so on), and if you wanted, you could remove what you don't need, or treeshake the image to reduce the size considerably. Running in a special-purpose VM, a real Lisp CPU or a JIT won't really make things that much better. Symbolics' Lisp Machines are actually considerably slower than having them emulated (emulating the Alpha port on x86_64). What those CPUs had going for them was the register size and tag bits which were natively part of the pointer, but aside from that, there's nothing wrong with how Lisps are done on modern machines (they still usually have the tag bits in the pointer, which may cost you precious address space in some implementations - this isn't really a problem on x86 64 of course).

Name: Anonymous 2010-04-06 14:27

>>17,18
Assembly languages don't need runtime support, so comparatively any runtime is monstrous. But the point was that there is a lot of work being done by the runtime, and had nothing to do with the amount of space it bloats your binary by. Should I have said smelly instead? I should have said elephantine.

Name: Anonymous 2010-04-06 15:02

Assembly languages don't need runtime support
Of course, 99% of the people advocating Assembly language programming in this day and age are retarded. Even embedded has been moving away for a while.

Name: Anonymous 2010-04-06 15:08

1-2MB on the smaller ones
Still, that's a million bytes.

Name: Anonymous 2010-04-06 15:10

>>19
Assembly language does have its own runtime most of the time. You have your OS to rely on, which sometimes can be quite large, and you have other libraries which you can call to. Even in bootloaders and other no-OS, no-runtime situations, you have the BIOS to rely on and all the mechanisms the CPU provide, which are quite a lot on x86(trig math, floating point ops, even a CRC32 instruction, and many more). You will have to make your own runtime if you have none. There is no shame in using one's everpresent runtime, that's what we have modern OSes, and if that runtime doesn't suit you, you're free to make your own, but you'll always need some sort of base libraries, there's no escaping from that, unless you really like to waste your time reinventing the wheel each time.

Name: Anonymous 2010-04-06 15:13

>>21
Have you checked the size of modern OSes like Linux or Windows? Do you know how much runtime they provide, it's in hundreds of MBs on normal OSes - of course you can cut them down to a few dozen or even a single floppy in extreme cases.

Besides, if you really are bothered by the huge runtime and treeshaking/cleaning up the image is not enough, and C-compiled Lisps are not enough, you could just use one of those very tiny lisps (lisp500 would be an example, or one of the many tiny Schemes) which compile to very little, but they're not the most efficient.

Name: Anonymous 2010-04-06 17:52

>>22
You're ignoring the fact that in assembly languages, every BIOS call is still a BIOS call, every OS call is an OS call and the main point: every library call is a library call. These are all external to the language itself; what the abstract code does on the machine is congruent with exactly what is written--give or take optimization (performed before assembly anyhow.) And, no, you don't need to make your own runtime to implement any language features.

This isn't about the bane of runtime support requirement, or that using a runtime is somehow bad. It's about the simple distinction that, technically speaking, assembly languages by definition don't have a certain requirement that others do.

This barely relevant yet concrete little fact offends everyone. Have a nice day, /prog/.

Name: Anonymous 2010-04-06 19:12

>>24
You still need to make those calls for most useful ASM programs, just like you have to do it for C or Lisp or whatever. The ``runtime''/libraries/... will always exist to some extent in any real world complex system. There's no shame in that, it's what makes computers actually useful/usable. While you don't have to call a library if you don't need it, the same is true for other languages too, not just asm. For example, you could implement a SHA256 library in asm, c or lisp, and it won't have to call any external library for its work, the c and lisp version could both be compiled efficiently into a tiny library providing you're using a good compiler or implementation that allows you to do that. Which makes high-level languages just as useful as ASM here. I've used C as a portable assembler quite a few times already. Don't assume mid/high-level languages can't be used in the same way you use assembler. You could for example, make a high-level assembler in Lisp, and use that to generate code which will be executed either at runtime or in other ways(cross-compile anyone?).

tl;dr: When everything compiles to ASM, everything can do the same things ASM can do, but to actually write real, large complex programs, you'll want to use some libraries or runtimes.

PS: If you think Lisp has any runtime "requirements", you're mistaken, it can be compiled to native code, however it's common for it to have a large library, but nothing stops you from just removing/not using that library.

Name: Anonymous 2010-04-06 19:45

>>25
Did you even read a single word?

I'd particularly like to point out that, on current architectures, LISP has language features that are in fact dependent on its runtime. It doesn't matter that the runtime is built from native code, it implements features which are both required and non-native. (Otherwise, grow a pair and make the case that LISP is an assembly.)

But my favorite part is where you insist on contradicting technicality by submitting an argument about practicality. Please keep doing that. It's awesome.

Name: Anonymous 2010-04-06 19:52

>>26
How about you point out these required features?

I've compiled a CL MD5 library to pure asm since all the arith/logic ops get inlined. You can do the same in C, just as easily.
If I were to take out those code objects, I could reuse them from other applications, just like native ASM code.

Name: Anonymous 2010-04-07 0:30

>>27
I don't think that you understood a single thing I just said. Please stop posting, you're embarassing yourself.

Name: Anonymous 2010-04-07 1:47

>>28
You actually don't know anything about Lisp, you just like pretending you do.

Name: Anonymous 2010-04-07 2:45

>>29
Back to your cons cell, please.

Name: Anonymous 2010-04-07 5:50

>>28
I don't think that you understood a single thing I just said.
LISP has language features that are in fact dependent on its runtime.
LISP

No, I don't think that you understand a single thing you just said.

Name: Anonymous 2010-04-07 9:13

>>27
Lists, for starters. It's a simple thing, but they do have functionality that is not congruent to machine operations and also never delineated in code the programmer uses--to spell it out, x86 etc. doesn't know what a linked list is, and neither does assembly presume to. So although I believe he was joking, >>30 almost has a point.

Name: Anonymous 2010-04-07 10:06

>>32
x86 also does not know what type system is.

Name: Anonymous 2010-04-07 10:38

>>32
Okay, first, Lisp doesn't have a linked list as a native type, instead all linked lists are built out of conses, this gives you the possibility to build nested lists which share structure, have circularities, etc.
A proper linked list is one which is either:
1)A Cons, the CAR points to the first element of the list
          the CDR points to another proper linked list
2)NIL (Symbol in CL, empty '() list in Scheme)
This is rather simple to describe in C, but I'll refrain from giving trivial translations/examples.
Now, the question is what is a CONS. A CONS is a structure of any 2 elements. In C, it could be represented as just 2 random void* pointers. Pretty much most modern Lisp compilers translate CAR and CDR as simple pointer dereferences as that's what they are, there's really no magic here. It's 1-3 instructions on x86 (for example, if a CONS is made of 2 DWORDS, and ECX points to a CONS, you could get the CDR in EAX by doing MOV EAX,DWORD PTR:[EDX+4], simple enough?). CONS itself can be thought of as in the more complex case, a simple malloc(sizeof(CONS)) call, and setting up the structure further(I'll explain in a few). All 3 operations can be inlined, and most list operations can be easily shown to revolve around these ops quite nicely. I could also show how one could represent just about any Lisp object in C or ASM if you need examples, altough I feel you would be better off reading the source code of the implementation.

What really sets Lisp apart though, is that each object is usually tagged internally with a base type, so a CONS, a FUNCTION, a STRING, an ARRAY, a BIGNUM, a STRUCTURE, a CLASS instance, and so on, are all basically data structures, but they have some space reserved for an object tag (be it, 8 bits, 4 bits, an int or whatever). There are many possible encodings, so there's no reason to discuss them all here, but just imagine that each object contains a field (for example a char) containing its type id before all the data. In some implementations, the tag bits may be part of the pointer... Other implementations may optimize fixnums(ints) to be unboxed under certain circumstances, and so on.

The thing is, you can still implement this in C, maybe with some slight hacks if more advanced/space conserative encodings are used, and without much trouble at all in ASM.

This tagging system is needed for most truly dynamically typed languages, and ensures operations work as they should, and do so in a relatively safe manner which allows for proper error handling, it also allows specializing by type and many other niceties.

The real point that should be made though, is that all these things are mere conventions an implementation chooses to obey, and once it comes down to metal, these are just simple instructions that get added by your compiler, and they function rather standalone. You could do the same in ASM or C, although, I can't imagine things would be very pleasant if you couldn't cover up all the redundancies - things which Lisp compilers and Lisp macros do an excellent job of hiding, and things which the programmer can extent as he wishes, without being bogged by the details more than once(or a few times when he maintains some specific module) - that's one basis of abstraction... but I'm getting offtopic here.

What I wanted to say is that CONS, CAR and CDR are congruent to machine ops quite nicely, and they're usually 1-2 ops. Maybe on a 64bit system, you could even represent a CONS as an unboxed register, if you wished, also, did you ever look at the origin of the names? They come from IBM 704 Assembler, and they were rather direct macros over that machine's assembler, and very low-level constructs. It's why we're still using these names today (of course, you're free to use FIRST/REST if you don't like CAR/CDR). I don't like linking to Wikipedia, but here, go ahead and read it: http://en.wikipedia.org/wiki/CAR_and_CDR

So not only is CAR/CDR translatable to 1-3 instructions on modern CPUs, it was always a low-level operation even during its inception, and you don't need a runtime to support it.

So what could a special purpose CPU make easier for Lisp? Tag bits! Those CPUs had dedicated tag bits which allowed typing the pointers and other data, which makes things much nicer for Lisp, while nowadays we don't really type our data, but rely on the compiler to set up the conventions as it pleases, as long as there's enough space in the register(if you plan on storing it in a reg-sized value, otherwise, if you're storing it part of the struct, there's no arch specific-trickery at all).

tl;dr: Lisp runtimes can sometimes be large, but they're large for different reasons than what someone in this thread thought - they're large because they tend to include compilers/interpreters, FFIs, and many other complex libraries with them. Things which can be stripped if not needed. Lisp code can be self-containing, just like ASM or C code, and doesn't have to depend on the runtime, more than any other kind of code - as long as the code that interacts with it follows proper conventions, or you have an FFI do the translation for you.

Name: 34 2010-04-07 12:10

I forgot to mention that since each object's type is known, and you can traverse all the data in the memory given some root object(s) (for example, a list of packages). This makes precise garbage collection possible. Such GCs tend to be written in C most of the time, and they're usually not too large (~100KB seems right). That's usually the major part of a runtime of an useful Lisp, but of course GC-less Lisps are perfectly possible, although probably not the smartest things around. The other low-level parts of the runtime usually deal with loading and mapping the image to memory form disk and vice-versa, and maybe some system call thunks. For example, SBCL's main executable, stripped of the bloated debug symbols is only 94KB here, and that includes all the load/save/gc functionality. If you used a C-compiled lisp, things would be slightly different, but not by that much. It might also be worth mentioning that on Lisp Machines, the GC, image fasl load/save were part of the OS(which was written in Lisp as well, like everything else), so those parts didn't have to be implemented in the executable, as the OS itself took care of those things. Of course, if you really look at what the low-level runtime usually contains, you'll see that if you wanted, you could do away with it and still have working code (with some changes to how images are written).

Well, whatever, I'm feeling this discussion is somewhat pointless as anyone can do whatever they want in any language, and everything is just limited to their imagination as long as they understand the architecture as well as how to design software.

Dynamic languages come with some overhead, but that overhead is in inherent extra typechecking operations, not "bloated runtimes" or "bloated libraries" (things which can exist, but are not required).

Name: Anonymous 2010-04-07 13:37

Lisp has eval built into the language. That pretty much necessitates the inclusion of a full interpreter in the runtime.

Amusingly enough, runtime code generation is easy in both Lisp and Asm, but not something like C (unless you count invoking the system C compiler and executing the result, which eliminates most of the performance benefits.)

Name: Anonymous 2010-04-07 14:11

>>33
That would be why no assembly language type errors occur at runtime. You'd have a great point if they did.

>>34,35
I'm going to skip to the part where you're still arguing about bloat. I want to remind you that I've never argued about bloat.
I don't care about whether it is efficient, whether it makes a good systems language or what have you, the only point I'm concerned with is what it truly is, vis-a-vis the runtime requirement. You're not contradicting that at all, but making it plainly obvious that you can't stand the observation.

Name: Not >>33,34,35... 2010-04-07 14:49

>>37
I don't get why you have this irrational hate of runtime. They buy you some flexibility in exchange for a certain performance penalty, no big deal.

x86 also does not know what type system is.
> That would be why no assembly language type errors occur at runtime. You'd have a great point if they did.

Are you agreeing or disagreeing with him? If you don't have a type system then you can't get a type error, that should be obvious to even the retards on /prog/

Name: Anonymous 2010-04-07 15:05

>>36
Lisp has eval built into the language.
Eval is not built into the language, eval is a Lisp program written in Lisp. Only the most primitive functions like cons, cdr, etc are part of the language itself

Name: Anonymous 2010-04-07 15:13

>>39
Well, it doesn't have to be. I'd imagine that incremental compilers like Ikarus use their normal compiler on eval.

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List