BASIC - more harmful than useful?

Drop in for a chat and a cup of tea

899 posts   Page 32 of 36   1 ... 29, 30, 31, 32, 33, 34, 35, 36
by tufty » Mon Feb 11, 2013 9:07 pm
If you don't know, don't disparage, then. Or at least do your homework first.

http://www.michaelnielsen.org/ddi/lisp- ... -software/
Posts: 1367
Joined: Sun Sep 11, 2011 2:32 pm
by jackokring » Mon Feb 11, 2013 10:33 pm
tufty wrote:
DavidS wrote:Lisp is stack based, and thus slower and slower as you build it up.

You what ahahahahahahahahahah you're funny. No, really. You should do geek standup. Or get a clue.


A list head is the top of a stack accessed by CDR and an assignment of the CAR to the stack symbol. Stack push on the other hand is managed by CONS. Think before you post.

It may be true this is more of a stack union with a tree, and the pointer indirection has an execution cost similar to virtual page table indexing. It's also true lisp is flawed by the dot (.) operator, as it forces the addressing to be user mode.

Stack is often taken to mean implemented as a bounded or unbounded array, with limited access semantics, but so all all Turing machines destined to use arrayed memory. They are called ABSTRACT data types, because they are not HARDWIRED data types.
Pi=B256R0USB CL4SD8GB Raspbian Stock. https://sites.google.com/site/rubikcompression/strictly-long https://dl.dropboxusercontent.com/u/1615413/Own%20Work/Leptronics.pdf https://groups.google.com/forum/#!topic/comp.compression/t22ct_BKi9w
User avatar
Posts: 784
Joined: Tue Jul 31, 2012 8:27 am
Location: London, UK
by rurwin » Tue Feb 12, 2013 12:47 am
Nobody ever said that Lisp was efficient. It certainly isn't, but to my mind the basic data type is the binary tree: CAR takes the left node, CDR takes the right node, and CONS creates a new node with the given left and right nodes. You can implement a stack using a degenerate tree, and most Lisp data structures are such degenerate trees, but I don't think it would be true to say that they are stacks. In fact they are less efficient than stacks because the locus of access is not localised.

jackokring wrote:lisp is flawed by the dot (.) operator, as it forces the addressing to be user mode.

Could you explain that?
User avatar
Forum Moderator
Forum Moderator
Posts: 2903
Joined: Mon Jan 09, 2012 3:16 pm
by jackokring » Tue Feb 12, 2013 1:01 am
rurwin wrote:Nobody ever said that Lisp was efficient. It certainly isn't, but to my mind the basic data type is the binary tree: CAR takes the left node, CDR takes the right node, and CONS creates a new node with the given left and right nodes. You can implement a stack using a degenerate tree, and most Lisp data structures are such degenerate trees, but I don't think it would be true to say that they are stacks. In fact they are less efficient than stacks because the locus of access is not localised.

jackokring wrote:lisp is flawed by the dot (.) operator, as it forces the addressing to be user mode.

Could you explain that?


(DATA . ADDRESS) is the usual format these cons cells are usually in. The dot operator is the only operator in lisp which can construct explicitly this type (DATA . DATA), i.e. where the address or link
pointer is not an address. It could be dereferenced as an address by many other words, causing a segmentation fault. Removing the dot operator, removes the possibility of segmentation fault IF the lisp is built without segmentation bugs. This means the memory can then be de-interleaved so that there is one large DATA array on the heap, and one large lab cache for all the ADDRESS memory cells. If the DATA heap offset is back poked into the lisp binary (self modified just the once on loading, perhaps by the kernal module which is the faster lisp), then all address pointers can be resolved without page table lookup. It does prevent virtual memory use for the cons cells, but ... at the cost of lower translation buffer stalls from the sprayed all over cons lists.

A simple reorder of CONS cells for proximity would also be useful for often used structures.
Pi=B256R0USB CL4SD8GB Raspbian Stock. https://sites.google.com/site/rubikcompression/strictly-long https://dl.dropboxusercontent.com/u/1615413/Own%20Work/Leptronics.pdf https://groups.google.com/forum/#!topic/comp.compression/t22ct_BKi9w
User avatar
Posts: 784
Joined: Tue Jul 31, 2012 8:27 am
Location: London, UK
by rurwin » Tue Feb 12, 2013 1:21 am
I'm not sure I follow exactly. But you are wrong on one point. It isn't the dot operator at fault.
Code: Select all
(CONS 1 2)
Will create the structure (1 . 2)
Or are you saying that . is a low level operator? I believe that CAR, CDR, CONS are the lowest level operators, and that . is in fact a function of the input parser and output formatter.

What you say may well be true, but it would break Lisp very badly, such that a huge proportion of existing programs wouldn't work. If a language was devised along the lines you suggest, it wouldn't be Lisp, and there are probably more efficient ways to implement one-dimensional lists if that was the only data structure you provided.

Anyway, the first cell of ((1 2) 3) has the form (ADDRESS . ADDRESS), which would break your memory allocation.
User avatar
Forum Moderator
Forum Moderator
Posts: 2903
Joined: Mon Jan 09, 2012 3:16 pm
by jackokring » Tue Feb 12, 2013 1:31 am
rurwin wrote:I'm not sure I follow exactly. But you are wrong on one point. It isn't the dot operator at fault.
Code: Select all
(CONS 1 2)
Will create the structure (1 . 2)
Or are you saying that . is a low level operator? I believe that CAR, CDR, CONS are the lowest level operators, and that . is in fact a function of the input parser and output formatter.

Yes, then the CONS operator should be removed, and all dependents should be recast in terms of APPEND. Except for stable internals which never expose the raw address.
What you say may well be true, but it would break Lisp very badly, such that a huge proportion of existing programs wouldn't work. If a language was devised along the lines you suggest, it wouldn't be Lisp, and there are probably more efficient ways to implement one-dimensional lists if that was the only data structure you provided.

Anyway, the first cell of ((1 2) 3) has the form (ADDRESS . ADDRESS), which would break your memory allocation.


BUT the address of (1 2) is constructed by the system (and I did state is was the second address which can go supervisor mode), it is not some random 123 crash. Both parts of the cons cell could be supervisor mode. And an interleave would actual help, so it shouldn't be done due to cache lines. A grouped locality is the minimum unit of fetch, and more importantly the minimum unit of storing (but only when changes occur). Writing something in 2 cache lines causes more writeback traffic on the memory bus, and so delays reads, as empty is done before refill in units of cache line.

ADDRESS is a subset of DATA if you want a stable faster system which needs less virtual protection. It is also why some languages should not be allowed to wright full speed (but hence slower) versions of themselves.
Pi=B256R0USB CL4SD8GB Raspbian Stock. https://sites.google.com/site/rubikcompression/strictly-long https://dl.dropboxusercontent.com/u/1615413/Own%20Work/Leptronics.pdf https://groups.google.com/forum/#!topic/comp.compression/t22ct_BKi9w
User avatar
Posts: 784
Joined: Tue Jul 31, 2012 8:27 am
Location: London, UK
by tufty » Tue Feb 12, 2013 7:19 am
rurwin wrote:Or are you saying that . is a low level operator? I believe that CAR, CDR, CONS are the lowest level operators, and that . is in fact a function of the input parser and output formatter.

Indeed. The low level memory allocator in a pure lisp (i.e. one without additional low level data types like arrays) is CONS. (1 . 2) is merely a shorthand for (CONS 1 2). You can't use "the dot operator" for anything else; it's syntactic sugar and not an operator.

As for this:

The dot operator is the only operator in lisp which can construct explicitly this type (DATA . DATA), i.e. where the address or link
pointer is not an address. It could be dereferenced as an address by many other words, causing a segmentation fault.

Again incorrect, unless your interpreter / compiler is incredibly naive and interprets any CDR or CAR dereference as a direct memory access. That's not the case, as otherwise *every* lisp "loop" through a well-formed list would cause a segmentation fault (NULL, the list delimiter, is not a pointer in most cases)

The typical approach (although not the only one possible) is to use tagged data. If we are dealing with a 32-bit machine, for example, we know that (at least) the low 2 bits at least of any word are going to be 0b00 for any address. So we can pack our data into 30 bits, and use the bottom 2 bits as tags. It's actually cleaner to treat 0b00 as a tag for numbers (which makes basic mathematical functions faster), use some other tag for addresses, and use offset addressing.

I'd post more, but a: this is a thread about BASIC and b: I have to go to work.

Simon
Posts: 1367
Joined: Sun Sep 11, 2011 2:32 pm
by jackokring » Tue Feb 12, 2013 8:07 am
tufty wrote:Again incorrect, unless your interpreter / compiler is incredibly naive and interprets any CDR or CAR dereference as a direct memory access. That's not the case, as otherwise *every* lisp "loop" through a well-formed list would cause a segmentation fault (NULL, the list delimiter, is not a pointer in most cases)

The typical approach (although not the only one possible) is to use tagged data.

I think the relevance to BASIC, although not obvious, is that speed does not equal ease of use. And the lesson for lisp is simplicity of data structure implementation does not equal speed or ease of use, but does provide some very useful abstract toolage.

I thought myself, that the self pointed NUL defined as ((SYMBOL-TYPE . (SELF . (CHAR-N . (CHAR-I . (CHAR-L . SELF)))) ) . SELF) was one of the nicest. :D
Pi=B256R0USB CL4SD8GB Raspbian Stock. https://sites.google.com/site/rubikcompression/strictly-long https://dl.dropboxusercontent.com/u/1615413/Own%20Work/Leptronics.pdf https://groups.google.com/forum/#!topic/comp.compression/t22ct_BKi9w
User avatar
Posts: 784
Joined: Tue Jul 31, 2012 8:27 am
Location: London, UK
by Bakul Shah » Tue Feb 12, 2013 6:11 pm
tufty wrote:
rurwin wrote:Or are you saying that . is a low level operator? I believe that CAR, CDR, CONS are the lowest level operators, and that . is in fact a function of the input parser and output formatter.

Indeed. The low level memory allocator in a pure lisp (i.e. one without additional low level data types like arrays) is CONS. (1 . 2) is merely a shorthand for (CONS 1 2). You can't use "the dot operator" for anything else; it's syntactic sugar and not an operator.

"." is not an operator, it is syntax. (1 . 2) is not a shorthand for (CONS 1 2). The latter builds a pair at run time. The former builds a pair at read time (data or program). During execution, if a program does (READ), and the input is (1 . 2), the returned value of (READ) will be (1 . 2). If the input is (CONS 1 2), the returned value will be (CONS 1 2). I know you know this, Simon, and were probably just in too much of a hurry to spell it all out but I don't want others to get (further) confused!

jackoring seems to assume (1 . 2) would be implemented as a pair with two *data* elements. But this is not a given. An implementation can choose to store a number elsewhere and use its address in the pair (and would be typically be forced do so if the number is so large as to not fit in the machine's native word length - any tags). And other tricks are possible. For instance, an implementation may decide to inline short strings so that ("abc" . "def") uses two words and no pointers! It doesn't help to look under the cover as it were if you are trying to learn lisp or Scheme until after you are familiar with the language. Bottom line: as long as the language semantics are implemented correctly, an implementer may use any tricks he wishes.
Posts: 293
Joined: Sun Sep 25, 2011 1:25 am
by tufty » Tue Feb 12, 2013 6:43 pm
Bakul Shah wrote:(1 . 2) is not a shorthand for (CONS 1 2). The latter builds a pair at run time. The former builds a pair at read time (data or program).

You're right. My bad, I realised what I'd written there was wrong halfway to work...
Posts: 1367
Joined: Sun Sep 11, 2011 2:32 pm
by johnbeetem » Tue Feb 12, 2013 6:45 pm
DavidS wrote:Ok, I guess I was wrong on that, I had never used Lisp because at a young age I was taught that it is a purely stack based language (in a negitiv way), and so I never looked into it any further. Though that was not my point anyway. My apology, there are languages that I have yet to use. I only had the word of my professor to go on.


General rule: don't believe everything you hear or read no matter what credentials the speaker or writer may have.

Lisp was designed as a language for reasoning about programs, not as a practical programming language. The utter simplicity of its basic operations (car, cdr, cons, cond, eq) makes reasoning about programs less intractable than conventional programming languages, which are so ridden with side-effects that reasoning is next to impossible.

Lisp took off as a programming language because it's very well suited to certain kinds of programming, such as symbolic programming where you're dealing with sets and multi-sets and tuples, and artificial intelligence. Lisp also took off because it was one of the first interactive programming languages when most people were writing batch Fortran programs on punched cards. The Lisp environment made it really easy to write a new function, test it with some examples, and then use that same function to build up other functions -- like playing with Lego bricks instead of starting a 3-hour 3-D printer job.

Lisp can be compiled into more efficient forms. For example, a good Lisp compiler can automatically detect forms of recursion that can be replaced with loops. This encourages you to write programs in their most logically understandable form, and let the compiler optimize it into something more efficient. Unfortunately, this is extremely hard to do in general and I don't know what the state of the art currently is.

There have been attempts to build symbolic machines for executing Lisp efficiently. I don't know if these failed because it's an impossible task or just because they never got quantities high enough to be economically viable.
User avatar
Posts: 942
Joined: Mon Oct 17, 2011 11:18 pm
Location: The Coast
by tufty » Tue Feb 12, 2013 6:53 pm
johnbeetem wrote:certain kinds of programming, such as symbolic programming

I would argue that /all/ programming is symbolic. There's a couple of rather good posts on Groklaw (admittedly they are long, difficult to read, and have a distinct "anti software patents" bias) by PoIR that explain the concept:
http://www.groklaw.net/article.php?stor ... 3192858600
http://www.groklaw.net/article.php?stor ... 9053154687

In a vague (and probably vain) attempt to pull this back on topic, remember what the "S" in BASIC stands for.
Posts: 1367
Joined: Sun Sep 11, 2011 2:32 pm
by johnbeetem » Tue Feb 12, 2013 7:57 pm
tufty wrote:
johnbeetem wrote:certain kinds of programming, such as symbolic programming

I would argue that /all/ programming is symbolic...

In a vague (and probably vain) attempt to pull this back on topic, remember what the "S" in BASIC stands for.

You can argue that and it's mathematically true. However, the techniques, languages, and machine-language instructions I use for numerical programming (such as inverting matrices and cross-correlation) are quite different from those I use for manipulating sets and multi-sets. So it's a useful distinction.

Regarding on-topicality, we are wondering if Basic is more harmful than useful. Some people argue that Basic teaches poor programming practices and imprints them at an impressionable age, while Lisp teaches good ways to think about and reason about programming. So Lisp is quite relevant to the topic at hand.
User avatar
Posts: 942
Joined: Mon Oct 17, 2011 11:18 pm
Location: The Coast
by rurwin » Tue Feb 12, 2013 10:00 pm
I find myself very tempted to devise a language without variables and where the only data-types are characters, floats and the hash tables, targeted for a data-flow machine.

What about this as a progression of study:

Logo
simplified assembler
Lisp
AVR assembler
Python
User avatar
Forum Moderator
Forum Moderator
Posts: 2903
Joined: Mon Jan 09, 2012 3:16 pm
by johnbeetem » Tue Feb 12, 2013 11:12 pm
rurwin wrote:What about this as a progression of study:

Logo
simplified assembler
Lisp
AVR assembler
Python

As I said 14 months ago on this thread, my first choice is still Pascal: viewtopic.php?f=47&t=1705&start=58
User avatar
Posts: 942
Joined: Mon Oct 17, 2011 11:18 pm
Location: The Coast
by simplesi » Wed Feb 13, 2013 12:02 am
What about this as a progression of study:

Logo


There is only ONE first language - and its called Scratch :)

No point in using Logo - Scratch can do Logo with one arm tied behind its back and you can move on with Scratch whereas Logo is a dead end - do't get me wrong - grearte language for learning computer programming but you can't do anything else with it after wards.

Simon
Seeking help with Scratch and I/O stuff for Primary age children
http://cymplecy.wordpress.com/ @cymplecy on twitter
Posts: 2041
Joined: Fri Feb 24, 2012 6:19 pm
Location: Euxton, Lancashire, UK
by rurwin » Wed Feb 13, 2013 12:35 am
Scratch is the dead end. Logo is a very full (list oriented) language; it's not just turtles.
User avatar
Forum Moderator
Forum Moderator
Posts: 2903
Joined: Mon Jan 09, 2012 3:16 pm
by DavidS » Wed Feb 13, 2013 3:08 am
Yes LOGO is a complete language. If I remember m history correctly (this was before my time) LOGO originaly did not have turtle graphcs, the turtle stuff whas added along with a robot (turtle) that executed the turtle commands.

I have only given a small look into Scratch though it apears to be a cmplete language, though with some more constraints than LOGO. Of cource I supose that ou could progress from Scratch to SmallTalk (in the form of Squeak), and SmallTalk is a language with out many limits.
ARM Assembly Language: For those that want: Simple, Powerful, Easy to learn, and Easy to debug.
User avatar
Posts: 1251
Joined: Thu Dec 15, 2011 6:39 am
Location: USA
by simplesi » Wed Feb 13, 2013 7:20 am
Scratch is the dead end. Logo is a very full (list oriented) language; it's not just turtles.


:)
Sorry - I'm talking about in the real world of teaching kids to program not in some abstract comp sci way :)

You put it down as first language - it used to be, because it was the simplest one to learn and teach and could be taught both on screen and by using real turtles.

But no child/teacher ever went on to do anyhting else with it.

Scratch has a much broader range for learning and teaching programming to kids :)

Scratch just IS the 1st language (as in Duplo/Lego is first construction toy)- all debates should be on what is the 2nd language :)

Simon
Did I mention my love for Scratch? :)
Seeking help with Scratch and I/O stuff for Primary age children
http://cymplecy.wordpress.com/ @cymplecy on twitter
Posts: 2041
Joined: Fri Feb 24, 2012 6:19 pm
Location: Euxton, Lancashire, UK
by rurwin » Wed Feb 13, 2013 7:37 am
I would probably agree that Scratch should be taught first, but I would push it back to before Logo rather than instead of. Make it primary school and introduce Logo in secondary school.

Scratch is a very nice way to introduce a lot of CS, but it is cutesy and constrained in its little box. It also doesn't have any aggregate data types, so it can't handle data processing. Try writing a Guess-the-animal game in Scratch.
User avatar
Forum Moderator
Forum Moderator
Posts: 2903
Joined: Mon Jan 09, 2012 3:16 pm
by jackokring » Wed Feb 13, 2013 8:35 am
rurwin wrote:... It also doesn't have any aggregate data types, so it can't handle data processing. Try writing a Guess-the-animal game in Scratch.


Aggregate types in BASIC, the array (hopefully more than 1D, or usable array pointers), and maybe records and lists, and if your lucky, function pointers, and maybe even classes. Maybe I'm thinking of older BASIC, but hash tables and ordered dictionaries can help with many tasks. Sure you can make them using arrays, and maybe the B in BASIC is useful for forcing you to write your own attempts, but if all you do when you meet a better language is reinvent the wheel using inferior rubber (as some algorithms are not obvious), it could harm the effectiveness of your shared code.

Study of these algorithms is important at some level, but at the basic level, it's too early. It's a waste of time which could be used on project furtherance. True you may never invent a better algorithm without knowing the best, but is that how you define useful?
Pi=B256R0USB CL4SD8GB Raspbian Stock. https://sites.google.com/site/rubikcompression/strictly-long https://dl.dropboxusercontent.com/u/1615413/Own%20Work/Leptronics.pdf https://groups.google.com/forum/#!topic/comp.compression/t22ct_BKi9w
User avatar
Posts: 784
Joined: Tue Jul 31, 2012 8:27 am
Location: London, UK
by simplesi » Wed Feb 13, 2013 11:22 am
o it can't handle data processing. Try writing a Guess-the-animal game in Scratch.

Very tempted to take up that challenge - I'll do it in summer hols when I've a bit of time on my hands :)


Logo was/is a great learning language and no doubt some will continue to push using it (a la people promoting BBC Basic are doing) but its time has gone - we don't want kids spending time on it when they won't use it for anything when then can use something else (that is ever so slightly harder to use at first) that they can then go home and carry on with it, make games, interact with others etc etc.

And once you've learned/taught Scratch, no-one is going to want to learn/teach Logo except as a CompSci module.

BTW Scratch owes a lot to Logo as Scratch contains so much of the Logo turtle philosophy (move, turn, repeat etc)

:)

Simon
Seeking help with Scratch and I/O stuff for Primary age children
http://cymplecy.wordpress.com/ @cymplecy on twitter
Posts: 2041
Joined: Fri Feb 24, 2012 6:19 pm
Location: Euxton, Lancashire, UK
by tufty » Sun Feb 17, 2013 7:04 pm
johnbeetem wrote:Lisp can be compiled into more efficient forms. For example, a good Lisp compiler can automatically detect forms of recursion that can be replaced with loops. This encourages you to write programs in their most logically understandable form, and let the compiler optimize it into something more efficient. Unfortunately, this is extremely hard to do in general and I don't know what the state of the art currently is.

The state of the art is probably Siskind's STALIN. It's quite capable of taking normally-written (although R4RS only) scheme, and turning it into something that kicks normally-written C code into touch in performance terms, despite using C as an intermediate language. It's particularly powerful for numerical stuff.
Posts: 1367
Joined: Sun Sep 11, 2011 2:32 pm
by Colly » Thu Jul 11, 2013 5:07 am
Interesting discussion - since kids themselves are actually being programmed as early as they can understand language: IF BEHAVE=TRUE THEN REWARD ELSE TREAT_DENIED. Kids that see that connection, will become programmers... or advertising executives. LOL!
Posts: 17
Joined: Mon Jul 16, 2012 4:27 am
by SiriusHardware » Sun Aug 18, 2013 9:39 am
spock wrote:basic isn't harmful but also not useful. :)

i always see those example here:
10 print "hello world!"
20 goto 10
and how great this is for kids.

in python the same is:
while 1: print "hello world!"
as great and with a useful modern language you can grow with. :)


Between those two, the first example is by far the most humanly understandable.

'while 1'

What does that even mean?

'While something one?'

'While something equals one', maybe?

While WHAT equals one?

It makes no sense in any programming language which uses that form. It would be a simple matter for Python, C etc to substitute 'while 1' with a special variant called 'forever'

forever: print 'Hello world'.

Now that would make sense when you read it, even if you had never read the language before.
Posts: 437
Joined: Thu Aug 02, 2012 9:09 pm
Location: UK