View Full Version : The Ultimate {Programmer} Holy War
evildave
11th March 2004, 12:24 PM
C is the ONE TRUE LANGUAGE. You will program everything in C...
Well, OK... unless it would be quicker to get it up and running in Python or some higher level language, or as a shell script.
And... yeah, maybe if you need to count clocks, assembly is what you really wanted. Been there, done that.
But all in all, C is the WAY!
But you can't just use C and claim to be adherent to my Plan!
Nay, the preprocessor was created by the good and mighty gods, K&R to do good works! No ASM programmer would work without a macro language on top of his ASM, and no C programmer should neglect the mighty CPP!
(Note: be sure and use archaic English for your written arguments (not necessary for your function or macro arguments.))
Abdul Alhazred
11th March 2004, 12:49 PM
What! No PL/1? :p
Nyarlathotep
11th March 2004, 12:54 PM
Yea, verily must I say RPG.
Not because it is a great language, for it is not, anon, but because it permeates all aspects of my life on this mortal coil.
All the day do I toil working in RPG.
Then on Saturdays, yea the day before the sabbath, do I get together with my friends and play RPG's
And indeed did one of my characters in that RPG once carry and use an RPG against a car.
And yea verily do I suck at speaking in Arcahic English.
Dymanic
11th March 2004, 01:13 PM
Planet X (that would be Lisp).
El Greco
11th March 2004, 01:20 PM
Real men program in hex
daenku32
11th March 2004, 01:51 PM
I'm a Secular programmer. Please don't smite me.
UserGoogol
11th March 2004, 02:00 PM
Different languages for different purposes. But Lisp is probably the best of them all.
Atlas
11th March 2004, 02:04 PM
I started out on an NCR/100. Programming language: NEAT/3. Big box. 32k Main Memory. The disk packs were portable and you had to open the top of the "washing machine" looking drive, twist, lift and then replace the pack with the data diskpack required for whatever jobstream you were going to run; Inventory, A/R, A/P, Order Entry. The company went belly up 6 months after I got there - Nobody said it was my fault, at least to my face. It was a good job too...$10,000 a year. Course I only saw $5,000 of it.
Then I landed in a DOS shop doing COBOL on an IBM 370 series. We'd write our program on coding sheets and the keypunch staff would transfer the code onto Hollerith punch cards and return them to us. We couldn't read the cards because they were just punched, so they had to be interpreted.
We took them into what later became know as the "Dinosaur Room". There you'd run the deck throuch the card interpreter and it would print the text on the top of the card that matched the punches. Then we'd go back to our desk and read through the cards marking the errors of the keypunch staff.Then back to the Dinosaur Room to get on a card repeater that would copy the first portion of the bad card up to the error. I'd stop there and correct the error and finish the code on that card. (Each card had 80 character positions.)
Then we'd bundle all the cards together and put a green compile card on the top and carry it to the operations window. They'd run it later and within an hour or two you'd usually have it back with a printout. Over just a couple of years improvements in computing dropped the compile time from around 15 minutes to 6 minutes and down to 2.5 minutes. Bad compiles are expected. We'd make the card corrections and try again. An efficient worker might get 3 compiles a day. We always used 6 digit dates on the cards unless we were hurting for space and then we'd use julian dates which were represented in 5. Year 2000 was a far distant idea on the horizon.
The data cards we used against our programs often needed resorting. The card sorter (another dinosaur) had 1 side where you loaded the cards. And they'd be processed on a single column and separated into 1 of about 40 dropslots (26 letters, 10 numbers, and a few special characters). A 16 character name sort required passing the deck through the sorter 16 times, reassembling the deck each time.
I later heard that in the early days of "Do Not Bend, Fold, Spindle or Mutilate this card" type of billings through the US mail, that for some large companies, a person's job description might be defined as "Card Sorter - Slot 12". A million customers to process undoubtedly took many hands.
My very first PC was a Commodore PET. 8k memory with a tape drive. Any little music cassette tape could be used to store your BASIC program. Pretty impressive little machine.
So your poll left out all my favorites. The BASIC of yesteryear had no Visual prefix to it's name.
If I were to manufacture a concept from today's acronyms to express my disdain for this new fangled world it would be: IP on C
Nyarlathotep: I learned a little RPG in school. If it's the same. Back then we referred to it as checkbox programming.
Nyarlathotep
11th March 2004, 02:24 PM
Originally posted by Atlas
Nyarlathotep: I learned a little RPG in school. If it's the same. Back then we referred to it as checkbox programming.
I don't know if I would call it checkbox programming but I'll be the first to admit that it isn't very hard. It's good for what it does but it isn't very versatile.
volant
11th March 2004, 02:31 PM
Sheesh, Chef (http://www.dangermouse.net/esoteric/chef.html) is the best language! :D
Yahweh
11th March 2004, 02:59 PM
I worship idols, I program in VisualBasic.
VisualBasic is not the one true Language, but He is supreme. Lesser languages include VBA, ASP / ADO, and to some extent BASIC.
Some may say VB was born from ALGOL and C, therefore being "inferior" to those languages. Quite the contrary, VB is a synthesis, and improvement. VB is so naturally easy to program, a child could learn to love it.
If you do not worship VisualBasic, you can kiss my syntax and go straight to DLL Hell.
Wudang
11th March 2004, 03:09 PM
Horses for courses.
Wudang
11th March 2004, 03:11 PM
[i]
If you do not worship VisualBasic, you can kiss my syntax and go straight to DLL Hell. [/B]
Molest me not with this pocket calculator stuff. Here's a quarter, kid, go buy yourself a better computer.
DLLs! We don't need no steeeeeenkin' DLLs.
toddjh
11th March 2004, 04:40 PM
Originally posted by Yahweh
I worship idols, I program in VisualBasic.
Amen, brother!
If C# is on the list, VB.NET should be too. The only advantage C# has over it is a C-like syntax that people take seriously. As a language VB is far superior.
Jeremy
P.S. Its compiler is better too.
evildave
11th March 2004, 05:09 PM
C++ is of Bjarne, the purple beast!
Operator overloading is sin.
C# is an abomination! A derivation of C that has to be interpreted.
scribble
11th March 2004, 06:26 PM
Originally posted by evildave
C# is an abomination! A derivation of C that has to be interpreted.
The difference between C and C# is akin to the difference between English and Microsoft-speak, which also has to be interpreted.
(majorly edited)
Janus
11th March 2004, 10:15 PM
Originally posted by evildave
Nay, the preprocessor was created by the good and mighty gods, K&R to do good works! No ASM programmer would work without a macro language on top of his ASM, and no C programmer should neglect the mighty CPP!
Never! Know not this week, typeless, indirection; for it is unclean to you. CPP is the product of men so poor, that their compilers passes could not become resident at the same time. Those on the true path to salvation seek out languages that insist upon purity of type be it: Generics (http://directory.google.com/Top/Computers/Programming/Languages/Ada/?tc=1), templates (http://directory.google.com/Top/Computers/Programming/Languages/C%2B%2B/), or functional substitution (http://directory.google.com/Top/Computers/Programming/Languages/ML/?tc=1).
Kilted_Canuck
11th March 2004, 11:19 PM
Meh, I am unskilled and only know BASIC, call me non-programmerist.
Kopji
11th March 2004, 11:59 PM
Forth is really stacked though.
epepke
12th March 2004, 12:56 AM
Originally posted by El Greco
Real men program in hex
Hex? What a wuss! Toggle switches and lights. Not even LEDs. Neon bulbs. Maybe a few patch cords, too.
And for the real real men, gears and shafts.
evildave
12th March 2004, 01:51 AM
Originally posted by Janus
Never! Know not this week, typeless, indirection; for it is unclean to you. CPP is the product of men so poor, that their compilers passes could not become resident at the same time. Those on the true path to salvation seek out languages that insist upon purity of type be it: Generics (http://directory.google.com/Top/Computers/Programming/Languages/Ada/?tc=1), templates (http://directory.google.com/Top/Computers/Programming/Languages/C%2B%2B/), or functional substitution (http://directory.google.com/Top/Computers/Programming/Languages/ML/?tc=1).
You speak as one who is unfamiliar with the ways of preprocessing.
The "fastest code" is never run at all.
When I write a set of macro to eliminate many lines of code for every line I need to type, I define whole new patterns of use.
#define MFG_CLASS(def) \
def( begin( MetaRec ) ) \
def( scalar( enum RecType, type, rtDot ) ) \
def( compound( Color, rgb ) ) \
def( scalar( i32, x, 0 ) ) \
def( scalar( i32, y, 0 ) ) \
def( scalar( i32, z, 0 ) ) \
def( end( MetaRec ) )
From this single declaration, I receive like a gift from heaven, the structure/class, the construction, the serialization, copying, comparison, XML I/O, database and logging code that I might otherwise have to maintain by hand. Instead, I need only add or change one line in the definition to rewrite functionality that I don't have to worry about. With a similar definition for the enum 'type', dispatch code can be generated which writes the entire XML, serial, etc. reading/writing interface.
In the case above, 'scalar' is a simple scalar value. A 'compound' is assumed to have its own constructor, destructor, comparison, serialization, etc based on a derived naming standard.
Indeed, once the code has been templated and filtered in this fashion, whole new levels of purity can be attained. You KNOW that a deep copy is available that will work right, allocating new references, etc. None of the initialization will be "forgotten", which means that fascinating class of bugs that show up *much later* will not happen at all.
Unlike lazily letting C++ do things, when you declare a template function in C using the preprocessor (which CAN be type-safe, and can in fact be used to declare and manufacture functions), you can see EXACTLY what code the C macro would generate. Because you can divorce the preprocessor stage from the compile stage.
Naturally, C++ can be used to do this, too. The preprocessor is an inseperable part of the language. For all the posing for what C++ templates "can do", the preprocessor still does things that C++ templates can not.
Stimpson J. Cat
12th March 2004, 02:03 AM
Anybody else remember Logo?
MRC_Hans
12th March 2004, 02:46 AM
Originally posted by Stimpson J. Cat
Anybody else remember Logo?
Trying hard not to, mate!
I voted C. Anything you can't write in C, cannot be written.
BASIC is like masturbation. It works better than nothing, most started with it, but few want to talk about it.
Hans
Filippo Lippi
12th March 2004, 04:35 AM
IF LANGUAGE NOT = 'COBOL' OR 'EASITRIEVE'
MOVE 12 TO RETURN-CODE
EXIT PROGRAM
END-IF
whitefork
12th March 2004, 08:56 AM
REXX is pretty good.
Whatever happened to APL and Algol?
I only do mainframes - I'm too old for this new stuff.
Atlas
12th March 2004, 09:12 AM
Originally posted by Kullervo
REXX is pretty good.
Whatever happened to APL and Algol?
I only do mainframes - I'm too old for this new stuff.
Whew, I was thinking I was the only lonely one but you and Filippo Lippi have both made me feel like the old world still exists within the new.
Go Codgers!
whitefork
12th March 2004, 09:31 AM
Remember that the dinosaurs ruled the earth for millions of years. I have a few left.
Proud to be writing in COBOL, REXX, IBM assembly language, and the occasional PL/1. The underlying instruction set has remained largely unchanged for 40 years. Gene Amdahl was a genius. So was Grace Hopper.
RandFan
12th March 2004, 09:51 AM
Originally posted by Kullervo
So was Grace Hopper. Damn straight! The most under recognized individual in the history of data processing IMHO.
I'm just a poser myself. VB and SQL front ends. I'm honored to be in your presense and it strokes my ego to just be able to understand what the hell you guys are talking about.
Oh, some JAVA and PERL when I was doing lots of HTML but that was the golden age of billing, before the darkness came, the reconciliation, when the gods of wall street learned that the value of a web site was only worth a fraction of its market price, if that is, it was worth anything at all.
evildave
12th March 2004, 02:32 PM
A Short Primer On Using CPP
The following example generates a structure definition, initialization code and printout code for a trivial example of the technique. I have far more "interesting" collections of macros that do a lot more. But that would be a whole library to post.
datagent.h
#ifndef DATAGEN_H
#define DATAGEN_H
#ifndef _NL_
#define _NL_
#endif
#define MAKEDECL( mbr ) DECL_##mbr
#define DECL_NAME( name ) struct name _NL_{_NL_
#define DECL_ENDDEF };_NL_
#define DECL_INT(label) int label;_NL_
#define DECL_FLOAT(label) float label;_NL_
#define MAKEPRINT( mbr ) PRINT_##mbr
#define PRINT_NAME( name ) void name##_Print( const struct name* pName )_NL_{_NL_ puts( #name "\n{\n" );_NL_
#define PRINT_ENDDEF puts( "\n};\n" );_NL_}_NL_
#define PRINT_INT(label) printf( "\t" #label " = %d\n", (pName)->label );_NL_
#define PRINT_FLOAT(label) printf( "\t" #label " = %g\n", (pName)->label );_NL_
#define MAKEINIT( mbr ) INIT_##mbr
#define INIT_NAME( name ) void name##_Init( struct name* pName )_NL_{_NL_
#define INIT_ENDDEF };_NL_
#define INIT_INT(label) (pName)->label = 0;_NL_
#define INIT_FLOAT(label) (pName)->label = 0.0f;_NL_
// Define struct, init and print
#define MAKE_STRUCT_AND_MEMBERS(def) \
def(MAKEDECL) \
def(MAKEPRINT) \
def(MAKEINIT) \
#endif // DATAGEN_H
example.c
#include <stdio.h>
#include "datagen.h"
#define DEF_MyStruct( edef ) \
edef( NAME( MyStruct ) ) /* My class name */\
edef( INT( id ) ) /* My class ID */\
edef( FLOAT( x ) ) /* Position */\
edef( FLOAT( y ) )\
edef( FLOAT( z ) )\
edef( ENDDEF )\
// Make all my structs
MAKE_STRUCT_AND_MEMBERS(DEF_MyStruct);
int main(void)
{
struct MyStruct tmp;
MyStruct_Init(&tmp);
MyStruct_Print(&tmp);
tmp.id = 1;
tmp.y = 100.0;
MyStruct_Print(&tmp);
}
cpp -P -CC example.c>blah.c
indent -ts=4 blah.c
vi blah.c
(copy/paste to post)
/*
* This has been tuned to generate reasonable code on the vax using pcc
*/
/* fast always-buffered version, true iff error */
// Define struct, init and print
// Make all my structs
struct MyStruct
{ /* My class name */
int id; /* My class ID */
float x; /* Position */
float y;
float z;
};
void
MyStruct_Print (const struct MyStruct *pName)
{
puts ("MyStruct" "\n{\n"); /* My class name */
printf ("\t" "id" " = %d\n", (pName)->id); /* My class ID */
printf ("\t" "x" " = %g\n", (pName)->x); /* Position */
printf ("\t" "y" " = %g\n", (pName)->y);
printf ("\t" "z" " = %g\n", (pName)->z);
puts ("\n};\n");
} void
MyStruct_Init (struct MyStruct *pName)
{ /* My class name */
(pName)->id = 0; /* My class ID */
(pName)->x = 0.0f; /* Position */
(pName)->y = 0.0f;
(pName)->z = 0.0f;
};;
int
main (void)
{
struct MyStruct tmp;
MyStruct_Init (&tmp);
MyStruct_Print (&tmp);
tmp.id = 1;
tmp.y = 100.0;
MyStruct_Print (&tmp);
}
D:\>cd Work\sample
D:\Work\sample>gcc example.c
D:\Work\sample>a
output
MyStruct
{
id = 0
x = 0
y = 0
z = 0
};
MyStruct
{
id = 1
x = 0
y = 100
z = 0
};
Note, _NL_ is something that can be defined to cpp (typically with a -D _NL_=_NL_ sort of syntax), so that you can use a tool such as 'sed' or 'tr' to rip through the cpp output and have the lines broken up for you.
If that doesn't sound appealing, simply grab 'gnu indent' and invoke it against the output of cpp. Instant readability.
phildonnia
12th March 2004, 02:36 PM
Let's get this out of the way first:
Pascal was the adding-machine guy. The punch-card guy was Jacquard, and his name only gets attached to nice tablecloths, not programming languages.
And let's get this out of the way too:
The "ultimate Holy war" is over which line do the open braces go on. The correct answer is: they go on whichever line you pay me to put them on.
---
I seem to be the kind of person who falls in love with each new language. When I learned Pascal, I couldn't possibly imagine anything with more ease and expressive power. My blindness was cured when I saw the light of Java, and I knew that I had finally realized the ultimate language.
Needless to say, today I write C#, which I consider far superior to any other past, future, or theoretically possible language.
---
This thread cannot be properly understood without a reference to this site:
http://www.99-bottles-of-beer.net/
Yahweh
12th March 2004, 02:54 PM
Originally posted by Kilted_Canuck
Meh, I am unskilled and only know BASIC, call me non-programmerist.
A bit of BASIC can accelerate how fast you learn to program graphing calculators.
(I'm always programming the calculators to do stupid things... note to all: Invest your free half-hour of classtime into something more constructive than writing JESUSPRGM on someone's unattended TI-89...)
Abdul Alhazred
12th March 2004, 03:12 PM
Originally posted by Kullervo
REXX is pretty good.
Whatever happened to APL and Algol?
I only do mainframes - I'm too old for this new stuff.
REXX is great. None of this BS about data types, everything is a variable length character string.
x = 32768 * 32768
i.x = 'Abdul Alhazred'
y = x||i.x
say x
say i.1073741824
say y
output:
1073741824
Abdul Alhazhed
1073741824Abdul Alhazred
scribble
12th March 2004, 03:36 PM
Originally posted by Stimpson J. Cat
Anybody else remember Logo?
They still use it to teach very young children the basics. I was going to find some link to some totally awesome logo program to make us all go "Wow, some idiot took the time to do THAT?" but sadly, googling for "logo programing" gets tons of logo-related hits, while adding "logo programming awesome" suddenly only matches 'logo" as in "this C++ programming book has an awesome logo."
Heh
scribble
12th March 2004, 03:39 PM
Originally posted by evildave
A Short Primer On Using CPP
... if you're going to use a C++ compiler, why not learn C++ instead?
Oh right... then that mess might actually be legible...
:P
evildave
12th March 2004, 03:47 PM
And now, for an 'stl' container. The following defines an invasive singly-linked list. This takes advantage of several things that can be done with a preprocessor that C++ templates can not do.
ll.h
#ifndef LL_H
#define LL_H
/**
* \file ll.h
* \brief "Invasive" Linked List C templates
* \author David Mace
*
* This is the simplest and fastest implementation of a linked list.
*
* It allows for the same object (provided multiple links) to be in multiple
* lists. Most invasive solutions don't allow that.
*
* Various lists can share the same link. In other words, the link for "free"
* and "in use" lists can be the same link in the structure/class.
*
* The doubly-linked list is compatible with the singly-linked one.
*
* Extremely low-overhead. Suitable for embedded solutions where you
* don't want to seperately allocate links.
*
* The singly linked list is FAR more efficient if you PUSH to the front,
* and mark for later deletion while some other (deletable) iteration is
* occurring.
*
* A bubble sort and fairly stable qsort (assuming the data really isn't)
* expected to be nearly sorted...)
*
* Template parameters:
* type Type of struct link resides in
* mlabel Name of the link member we're linking with in that struct
* ilabel Name of the list instance we're dealing with
*
* Generally, these are meant to be put into functions that perform operations,
* rather than be operations and interfaces unto themselves. Like STL, massive
* code bloat can result from careless use of some of these macros.
*
* Two tools are your best friend when dealing with these macros:
* cpp: The c preprocessor. Most comilers will do this job with a flag.
* indent (or equivalent): The gnu code beautifier.
*
* If there are problems, preprocess into a file and 'indent' the file to make it
* viewable. You'll generally want to make a batch/script that does the job with
* the appropriate search paths and flags for your project. Paste the functions/code
* that are giving you grief (at compile or run time) into your code where the macro
* expanded, and comment out the macro invokation. Now you can step through the result
* and see the errors clearly. Don't forget to put the ORIGINAL code back, or you'll
* sit there like an fool making changes, wondering why they don't have effects.
*
* You may even want to add a step to your makefile to preprocess (preserving line
* formatting, comments, etc.) and indent the result while building. Doing it this way
* you will always get to "step" the actual code that was generated, which is a BIG
* winning factor over C++ templatss. CPP is actually quite fast when you keep the
* dependencies in check. So is indent. I wish compilers had a mode to generate
* their output based on this behavior.
*
* This preprocess/indent technique is also useful for "source code" or "object code"
* distributions that you don't want to be changed or "hacked". Once a certain amount of
* repetitive code exists, making changes and having them work goes from progressively
* more difficult to nearly impossible. In case you're evil.
*
* More on this in the bigger, fatter, nastier macro behavior.
*
*/
// If assert hasn't been included, skip extra sanity checks
#ifndef assert
#define assert(v)
#endif
// Include definitions for debug helpers and such
#ifndef CDEFS_H
#include "cdefs.h"
#endif
/*
* Singly Linked List Template
*
* Basically a singly linked list is a handy, speedy little thing when
* used properly, and awful when used improperly. The two important
* bits are PUSH new members, and remove members while iterating,
* rather than forcing an iteration to remove them.
*
* Any link in the singly linked list can be treated as a subset of
* the whole list. Changling the links is about as fast as doing
* the saimilar operations with an array of pointers, except they're
* scattered.
*
* This implementation assumes only ONE pointer to the base of the
* list. Some sll implementations include a tail pointer. If you
* want a tail, just add it. I don't; it's extra stuff to keep
* track of and keep up to date. If you want to get at something
* from *either* end, and insert/remove links without, extra
* iteration, then use the doubly-linked list (below) instead.
*
*/
/**
* Declare a singly linked list "next" member template
*/
#define sll_decllink(type,mlabel)\
type* mlabel
/**
* Initialize a link
*/
#define sll_initlink(type,mlabel, curr)\
(curr)->mlabel = NULL
/**
* Declare a singly linked list template
*/
#define sll_decllist(type,mlabel, ilabel)\
type* ilabel
/**
* Make a singly linked list initially empty
*/
#define sll_initlist(type,mlabel, ilabel ) \
(ilabel) = NULL
/**
* Initialize a singly linked list from an array of objects
* ilabel: Pointer to ilabel member in linked list
* array: Pointer to start of array of members
* count: Count of members in array
*/
#define sll_initarray(type,mlabel, ilabel, array,count) \
{\
type* __ll_curr = (array);\
int __ll_remain = (count)-1;\
(ilabel) = __ll_curr;\
while ( __ll_remain-- )\
{\
__ll_curr->mlabel = __ll_curr+1;\
__ll_curr++;\
}\
__ll_curr->mlabel = NULL;\
}
/**
* Unlink all members
* ilabel: Pointer to ilabel member in linked list
*/
#define sll_reset(type,mlabel, ilabel) \
{\
type* __ll_curr = (array);\
type* __ll_next;\
while( __ll_curr ) \
{\
__ll_next = __ll_curr->mlabel;\
__ll_curr->mlabel = NULL;\
__ll_curr = __ll_next;\
}\
(ilabel) = NULL;\
}
/**
* Iterate to next member
* curr: Pointer to current, to be modified to next
*/
#define sll_next(type,mlabel, ilabel, curr ) \
((curr) = (curr) ? ((curr)->mlabel) : NULL)
/**
* Iterate through all members of a singly linked list
* This is the simplest and fastest way to do it, but you can't modify the list while you do it.
* This will generally need to be wrapped in its own {} scope
* ilabel: Pointer to head of list
* iterator: What you want to call the iterator
*/
#define sll_foreach_const(type,mlabel, ilabel, iterator ) \
const type* iterator = (ilabel); /* In C++, this declaration can be in the for loop. */\
for ( ; iterator; iterator = iterator->mlabel )
/**
* Iterate through all members of a singly linked list
* This is the simplest and fastest way to do it, but you can't modify the list while you do it.
* This will generally need to be wrapped in its own {} scope
* ilabel: Pointer to head of list
* iterator: What you want to call the iterator
*/
#define sll_foreach(type,mlabel, ilabel, iterator ) \
type* iterator = (ilabel); /* In C++, this declaration can be in the for loop. */\
for ( ; iterator; iterator = iterator->mlabel )
/**
* Iterate through all members of a singly linked list, allowing deletions
* This will generally need to be wrapped in its own {} scope
* ilabel: Pointer to head of list
* iterator: What you want to call the iterator
*/
#define sll_foreach_deletable(type,mlabel, ilabel, iterator ) \
type* __ll_##iterator##_prev = NULL; \
type* iterator = (ilabel);\
type* __ll_##iterator##_next = iterator?iterator->mlabel:NULL; \
for ( ; iterator; __ll_##iterator##_prev = iterator, iterator = __ll_##iterator##_next, sll_next(type,mlabel, ilabel, __ll_##iterator##_next ) )
/**
* Iterate through all members of a singly linked list; list will be reversed after this is done
* This will generally need to be wrapped in its own {} scope
* Why? It's often necessary during animation cycles to do a list forwards, then backwards. Do it twice to get original list
* ilabel: Pointer to head of list
* iterator: What you want to call the iterator
*/
#define sll_foreach_deletable_reverse(type,mlabel, ilabel, iterator ) \
type* __ll_##iterator##_prev = NULL; \
type* iterator = (ilabel);\
type* __ll_##iterator##_next = iterator?iterator->mlabel:NULL; \
for ( ; iterator; iterator->mlabel = __ll_##iterator##_prev, __ll_##iterator##_prev = (ilabel) = iterator, iterator = __ll_##iterator##_next, sll_next(type,mlabel, ilabel, __ll_##iterator##_next ) )
/**
* ONLY in sll_FOREACH_DELETABLE, safely remove current member during iteration
* ilabel: Pointer to head of list
* iterator: What the iterator was called in this loop
*/
#define sll_foreach_deletecurr(type,mlabel, ilabel, iterator ) \
if( iterator )\
{\
if ( __ll_##iterator##_prev )\
{\
__ll_##iterator##_prev->mlabel = __ll_##iterator##_next;\
}\
else\
{\
ilabel = __ll_##iterator##_next;\
}\
iterator->mlabel = NULL;\
}
/**
* Push a new item onto the singly linked list
* (Last-In-First-Out)
* ilabel: Pointer to head of list
* item: What to add
*/
#define sll_push_front(type,mlabel, ilabel, item ) \
{\
(item)->mlabel = (ilabel);\
(ilabel) = (item);\
}
/**
* Add a new item onto the FAR END of the list
* Use sll_push_front whenever possible: This has to iterate through the whole list!
* ilabel: Pointer to head of list
* item: What to add
*/
#define sll_push_back(type,mlabel, ilabel, item ) \
{\
type* __ll_iterate_add;\
sll_back(type,mlabel, ilabel, __ll_iterate_add );\
if( __ll_iterate_add ) \
{ \
__ll_iterate_add->mlabel = (item);\
} \
else \
{ \
(ilabel) = (item);\
} \
(item)->mlabel = NULL;\
}
/**
* Get ilabel item
* ilabel: Pointer to head of list
* get: Pointer to receive value
*/
#define sll_front(type,mlabel, ilabel, get ) \
{(get) = (ilabel);}
/**
* Get last item
* ilabel: Pointer to head of list
* get: Pointer to receive value
*/
#define sll_back(type,mlabel, ilabel, get ) \
{\
type* __ll_iterate = (ilabel);\
if( __ll_iterate ) \
while( __ll_iterate->mlabel )\
__ll_iterate = __ll_iterate->mlabel;\
(get) = __ll_iterate;\
}
/**
* Pop ilabel item off
* (Last-In-First-Out)
* ilabel: Pointer to head of list
*/
#define sll_pop_front(type,mlabel, ilabel, get ) \
{\
(get) = (ilabel);\
(ilabel) = (get)->mlabel;\
(get)->mlabel = NULL;\
}
/**
* Pop ilabel item off
* (Last-In-First-Out)
* ilabel: Pointer to head of list
*/
#define sll_pop_back(type,mlabel, ilabel, get ) \
{\
type* __ll_iterate = (ilabel);\
type* __ll_iterate_prev = NULL;\
if( __ll_iterate ) \
{\
while( __ll_iterate->mlabel )\
{\
__ll_iterate_prev = __ll_iterate->mlabel;\
__ll_iterate = __ll_iterate->mlabel;\
}\
if( __ll_iterate_prev )\
{\
__ll_iterate_prev = NULL;\
}\
else\
{\
(ilabel) = NULL;\
}\
}\
(get) = __ll_iterate;\
}
/**
* Seek a member and remove it
* ilabel: Pointer to head of list
* item: Item to remove
*/
#define sll_erase(type,mlabel, ilabel, item ) \
{\
type* __ll_iterate_remove##_prev = NULL; \
type* __ll_iterate_remove = (ilabel); \
while( __ll_iterate_remove )\
{\
if ( __ll_iterate_remove == (item) )\
{\
if ( __ll_iterate_remove##_prev )\
{\
__ll_iterate_remove##_prev->mlabel = __ll_iterate_remove->mlabel;\
}\
else\
{\
ilabel = __ll_iterate_remove->mlabel;\
}\
break;\
}\
__ll_iterate_remove##_prev = __ll_iterate_remove;\
__ll_iterate_remove = __ll_iterate_remove->mlabel;\
}\
}
/**
* Seek member(s) in the list and remove it(them) based on a callback
* ilabel: Pointer to head of list
* criteria: A boolean macro or function that takes a list member pointer and returns non-zero if it should be removed
*/
#define sll_remove_filter(type,mlabel, ilabel, criteria ) \
{\
sll_foreach_deletable(type,mlabel, ilabel, __ll_iterate_delete )\
{\
if ( criteria(__ll_iterate_delete) ) \
sll_foreach_deletecurr(type,mlabel, ilabel, __ll_iterate_delete ); \
}\
}
/**
* Seek member(s) in the list and move it(them) to "target" based on a callback
* ilabel: Pointer to head of list
* criteria: A boolean macro or function that takes a list member pointer and returns non-zero if it should be removed
* target: List to receive removed items (such as a "free" list)
*/
#define sll_move_filter(type,mlabel, ilabel, criteria, target ) \
{\
sll_foreach_deletable(type,mlabel, ilabel, __ll_iterate_move )\
{\
if ( criteria(__ll_iterate_move) ) \
{\
sll_foreach_deletecurr(type,mlabel, ilabel, __ll_iterate_move ); \
sll_push_front(type,mlabel, target, __ll_iterate_move );\
}\
}\
}
/**
* Tally members
* ilabel: Pointer to head of list
* count: Variable to receive member count
*/
#define sll_size(type,mlabel, ilabel, count) \
{\
type* __sll_size_iterator = (ilabel);\
for ( count = 0; __sll_size_iterator; __sll_size_iterator = __sll_size_iterator->mlabel, count++ )\
;\
}
/**
* Tally members and compare to a count
* ilabel: Pointer to head of list
* count: Count we're expecting
*/
#define sll_assert_size(type,mlabel, ilabel, count) \
{\
int __tally;\
sll_size(type,mlabel, ilabel, __tally);\
assert( __tally == (count) );\
}
/**
* Append members from one singly linked list (OF THE SAME KIND) to another
* toFirst: Pointer to head of the list that will contain both lists
* fromFirst: Pointer to the head of the list that will be empty after this
*/
#define sll_splice(type,mlabel, toFirst, fromFirst) \
{\
type* sllTail;\
if( toFirst ) \
{\
sll_back(type,mlabel, toFirst, sllTail );\
sllTail->mlabel = (fromFirst);\
}\
else\
{\
(toFirst) = (fromFirst);\
}\
(fromFirst) = NULL;\
}
/**
* Sort members by some criteria
* ilabel: Pointer to first member
* compare: Takes compare(prev,next), returns >0 if prev > next, < 0 if prev < next, or ==0 if prev == next.
* This is a BUBBLE sort.
* Bubble sort is GOOD for data that's nearly sorted; it's basically what the last stages of qsort look like.
* GOOD for 2D animation where things stay around and are sorted (for instance) by "Y", but AWFUL if you keep inserting and deleting things
* Push new things onto the front, and Sort will find its place
* Compare can be a macro or a function.
*/
#define sll_bsort(type,mlabel, ilabel, compare ) \
{\
if( (ilabel) && (ilabel)->mlabel )\
{\
type* first = ilabel;\
type* sortBefore, *sortPrev, *sortNext;\
int sorted;\
do\
{\
sorted = 0;\
sortBefore = NULL;\
sortPrev = first;\
sortNext = sortPrev->mlabel;\
while( sortNext )\
{\
if( compare( sortPrev, sortNext ) > 0 )\
{\
if( sortBefore )\
{\
sortBefore->mlabel = sortNext;\
}\
else\
{\
first = sortNext;\
}\
sortPrev->mlabel = sortNext->mlabel;\
sortNext->mlabel = sortPrev;\
sorted++;\
}\
sortBefore = sortPrev;\
sortPrev = sortNext;\
sortNext = sortNext->mlabel;\
}\
}\
while( sorted );\
ilabel = first;\
}\
}
/**
* Sort members by some criteria
* ilabel: Pointer to first member
* compare: Takes compare(prev,next), returns >0 if prev > next, < 0 if prev < next, or ==0 if prev == next.
* name: What to call the function you generated
*
* This function needs to be used at least two parts.
* The first part generates the function.
* sll_mfg_qsort(type,mlabel, ilabel, compare, name )
*
* If it needs to be accessible by other code, you may generate the function declaration with
* sll_decl_qsort(type,mlabel, ilabel, compare, name )
*
* Then invoke the sort with
* sll_qsort(type,mlabel, ilabel, compare, name )
*
* This qsort is reasonably fast compared to a bubble sort when the data is NOT nearly sorted.
* If there are a lot of things out of place in different parts of the list, this will be faster.
* If there are few things out of place, and the list is almost or completely sorted, this will be slower.
*
*/
// Declare a qsort
#define sll_decl_qsort(type,mlabel, ilabel, compare, name ) \
SLL_QSORT_##name( type** ilabel )
// Perform a qsort we previously constructed
#define sll_qsort(type,mlabel, ilabel, compare, name ) \
SLL_QSORT_##name( &(ilabel), NULL );\
#define MIN_WORTHWHILE_QSORT 8
// Build a qsort
#define sll_mfg_qsort(type,mlabel, ilabel, compare, name ) \
void SLL_QSORT_##name( type** front, type** back )\
{\
if( *front && (*front)->mlabel )\
{\
type* lesser = NULL;\
type* tlesser = NULL;\
type* greater = NULL;\
type* tgreater = NULL;\
type* equal = *front;\
type* tequal = equal;\
type* curr = equal->mlabel;\
while( curr )\
{\
type* next = curr->mlabel;\
int val = compare(equal,curr);\
if( val > 0 )\
{\
if( tlesser )\
{\
tlesser->mlabel = curr;\
tlesser = curr;\
}\
else\
{\
tlesser = lesser = curr;\
}\
}\
else if( val < 0 )\
{\
if( tgreater )\
{\
tgreater->mlabel = curr;\
tgreater = curr;\
}\
else\
{\
tgreater = greater = curr;\
}\
}\
else /* val==0 */\
{\
assert(val==0);\
tequal->mlabel = curr;\
tequal = curr;\
}\
curr = next;\
}\
/* Terminate lists */\
if( lesser )\
{\
tlesser->mlabel = NULL;\
if( lesser != tlesser )\
{\
tlesser->mlabel = NULL;\
SLL_QSORT_##name( &lesser, &tlesser );\
}\
}\
/* equal are all the same value... */\
if( greater )\
{\
tgreater->mlabel = NULL;\
if( greater != tgreater )\
{\
SLL_QSORT_##name( &greater, &tgreater );\
}\
}\
/* Splice lists together again */\
if( tlesser )\
{\
*front = lesser;\
tlesser->mlabel = equal;\
}\
else\
{\
*front = equal;\
}\
tequal->mlabel = greater;\
if( back )\
*back = tgreater ? tgreater : tequal;\
}\
}
#endif // LL_H
unit.c
/**
* Unit test for C templates
*/
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int nFailures = 0;
#define TEST_CHECK( condition ) \
if( !(condition) )\
{\
printf( "Failed " #condition "\nLine %d of %s\n", __LINE__, __FILE__ );\
nFailures++;\
}
#undef assert
#define assert TEST_CHECK
#include "ll.h"
#include "ByteArray.h"
typedef struct TestThing
{
sll_decllink( struct TestThing, t1next );
sll_decllink( struct TestThing, t2next );
int value;
} TestThing;
#define BIGGER(t1,t2) ((t1)->value - (t2)->value)
sll_mfg_qsort(TestThing,t1next, test1, BIGGER, SortBigger);
#undef BIGGER
// Test singly linked list macros.
void Test_SLL(void)
{
TestThing a1[30];
TestThing leftover;
sll_decllist(TestThing,t1next, test1);
sll_decllist(TestThing,t2next, test2);
sll_decllist(TestThing,t1next, scratch1);
sll_decllist(TestThing,t2next, scratch2);
sll_initlist(TestThing,t1next, scratch1);
sll_initlist(TestThing,t2next, scratch2);
{
ARRAY_FOREACH( TestThing, a1, curr )
{
curr->value = (int)indexof(a1,curr);
}
}
sll_initarray(TestThing,t1next, test1, a1, countof(a1));
sll_initarray(TestThing,t2next, test2, a1, countof(a1));
{
int count;
sll_size(TestThing,t1next, test1, count);
TEST_CHECK( count == countof(a1) );
sll_size(TestThing,t1next, test2, count);
TEST_CHECK( count == countof(a1) );
}
{
sll_foreach_deletable_reverse(TestThing,t1next, test1, fwd )
{
//printf( "%d ", fwd->value );
}
//printf( "\n" );
}
{
sll_foreach_deletable_reverse(TestThing,t1next, test1, fwd )
{
//printf( "%d ", fwd->value );
}
//printf( "\n" );
}
#define ODD(v) ((v)->value & 1)
sll_remove_filter(TestThing,t1next, test1, ODD );
#define EVEN(v) !((v)->value & 1)
sll_remove_filter(TestThing,t2next, test2, EVEN );
{
int count;
sll_size(TestThing,t1next, test1, count);
TEST_CHECK( count == countof(a1)/2 );
sll_size(TestThing,t2next, test2, count);
TEST_CHECK( count == countof(a1)/2 );
}
// See if odd-filtered array is all odd, now
{
sll_foreach(TestThing,t1next, test1, fwd )
{
//printf( "%d ", fwd->value );
TEST_CHECK( !(fwd->value & 1) );
}
//printf( "\n" );
}
// See if even filtered array is all even, now
{
sll_foreach(TestThing,t2next, test2, fwd )
{
//printf( "%d ", fwd->value );
TEST_CHECK( fwd->value & 1 );
}
//printf( "\n" );
}
//printf( "\n" );
// Re-init pool from scratch
sll_initarray(TestThing,t1next, test1, a1, countof(a1));
sll_initarray(TestThing,t2next, test2, a1, countof(a1));
// #define ODD(v) ((v)->value & 1)
sll_move_filter(TestThing,t1next, test1, ODD, scratch1 );
sll_splice(TestThing,t1next, test1, scratch1);
// #define EVEN(v) !((v)->value & 1)
sll_move_filter(TestThing,t2next, test2, EVEN, scratch2 );
sll_splice(TestThing,t2next, test2, scratch2);
{
int count;
sll_size(TestThing,t1next, test1, count);
TEST_CHECK( count == countof(a1) );
sll_size(TestThing,t2next, test2, count);
TEST_CHECK( count == countof(a1) );
}
leftover.value = -1;
leftover.t1next = leftover.t2next = NULL;
sll_push_back( TestThing,t1next, test1, &leftover );
sll_qsort(TestThing,t1next, test1, BIGGER, SortBigger);
#define SMALLER(t1,t2) ((t2)->value - (t1)->value)
sll_bsort(TestThing,t2next, test2, SMALLER );
// See if both arrays are sorted.
{
int prev = -1000;
sll_foreach(TestThing,t1next, test1, fwd )
{
TEST_CHECK( prev < fwd->value );
//printf( "%d ", fwd->value );
prev = fwd->value;
}
//printf( "\n\n" );
}
// See if even filtered array is all even, now
{
int prev = 1+countof(a1);
sll_foreach(TestThing,t2next, test2, fwd )
{
TEST_CHECK( prev > fwd->value );
//printf( "%d ", fwd->value );
prev = fwd->value;
}
//printf( "\n" );
}
#undef ODD
#undef EVEN
#undef SMALLER
}
// Invoke the tests
int main(void)
{
printf( "Test run of various container thingies.\n" );
srand((int)time(NULL));
Test_SLL();
printf( "\nCompleted with %d failures.\n", nFailures );
return nFailures;
}
evildave
12th March 2004, 04:27 PM
Originally posted by scribble
... if you're going to use a C++ compiler, why not learn C++ instead?
Oh right... then that mess might actually be legible...
:P
Actually, I do know and use C++. And the technique you see where the repetitive constructor, code, serialization, logging, etc. is generated *FOR YOU* is NOT supported by anything but the preprocessor that comes with C++.
In other words, why don't you learn to use the features of C++, including its built in preprocessing capabilities?
You want to see "evil" preprocessor stuff, go download BOOST C++ (what they call "best practices" for C++) and look at what they did.
In the second example, when using a C++ template methodology, GCC/G++ actually complains about offsetof being used in class definitions, with no way to turn the damned warning off (other than "tricking" it), which is a big shame because the stl-compatible invasive containers I have written in C++ actually work "OK"... but all contain some additional macro magic ANYWAY to bind the class and link contents. This can be used directly with the datagen technique I outlined, specifying that links to lists exist, and generating the appropriate class members for invasive container membership directly. In addition, the fact that a list member is linked to a list can be seen directly in most debuggers.
Anybody who thinks that anything beyond trivial C++ templates are "readable" definitely has a screw loose. The hoops you have to hop through to get things working can be nightmarish compared to the trivial token pasting and naming conventions that it takes to make C do the same things, and things that can't be done at all with C++ templates. You can also decide exactly where the C template code generates its functions, and how it exports them.
Janus
12th March 2004, 05:14 PM
Originally posted by evildave
You speak as one who is unfamiliar with the ways of preprocessing.
If only I wasn't familiar with the ways of the preprocessor. As a C++ programmer I know full well, how useful and necessary a preprocessor can be. But cpp is deficent in many ways. It is too week to be truly useful, yet so abusable that it requires a level of skill to avoid mauling the code (or your coworkers mauling you). It would be a moot point if there were no alternative, but in fact the world is abundent with better alternatives. For example ocampl4 can extend the language syntax, and intergates far better with the caml compiler.
As for your examples, I see nothing there that would persuade me to give up the improved compile time diagnostics and debugging that the equivent 1st class language features provide.
Originally posted by scribble
... if you're going to use a C++ compiler, why not learn C++ instead?
Oh right... then that mess might actually be legible...
:P
CPP != C++. cpp is the preprocessor, and present in both c and c++ compilers.
Earthborn
12th March 2004, 05:52 PM
What is it with those programming languages where you have to end every frickin' line with a semi-colon? Why, why why? I want a line to end when the line ends gosh darned! And why a semi colon ?
And what's up with programming languages with case sensitive variable names? Huh? Oh, of course I want xcoord to mean something entirely different than Xcoord or XCoord and it can't possibly be a typing error. Nooo...
Sorry people, it's still QBasic for me. It is simply the bestest. When it comes to byte length, when EvilDave is still declaring his variables, my cool graphics demo thingie is already finished:SCREEN 9, , 1, 0: a = 12: b = 6: c = .1: WINDOW (-100, -100)-(100, 100)
10 : k = INT(RND * 360): FOR l = 0 TO a STEP c: FOR w = 0 TO 359 STEP b
x1 = 100 * SIN(w): y1 = 100 * COS(w): x2 = 100 * (SIN(w + l))
y2 = 100 * (COS(w + k)): LINE (x1, y1)-(x2, y2): NEXT
IF INP(96) = 1 THEN SCREEN 0: SYSTEM ELSE PCOPY 1, 0: CLS
NEXT: GOTO 10Coded for compactness, not clarity. And I replaced the DO...LOOP for a GOTO loop just to spite you all!
Atlas
12th March 2004, 06:14 PM
Originally posted by Earthborn
And I replaced the DO...LOOP for a GOTO loop just to spite you all! GOTO... AHHHHH!
She's a WITCH.... Burn Her!
evildave
12th March 2004, 10:42 PM
'goto' is a C keyword. It does basically the same thing.
Don't want to end a statement with a ';'?
#define _z ;
Now you can end every line with '_z', if you like.
You could also do something like...
#define BEGIN {
#define END }
... if Pascal's your favorite.
If you want compact code, go to
http://www0.us.ioccc.org/main.html
This one is my current favorite.
http://www0.us.ioccc.org/2001/bellard.c
Though this one used to be - and should be Earthborn's favorite.
http://www0.us.ioccc.org/1990/dds.c
Janus
You just KNOW I will disagree with your assertion about CPP's 'weakness'. Actually, if CPP had regular expression syntax, I'd like it even more. Recursion would make it better, but the thing I just *LOVE* about it is that it's always there.
You're right about my examples. They don't really convey the message. When I literally get the nearly 100:1 decrease in code that I personally need to maintain, CPP shows its usefulness.
I have had team members who utterly rebelled against the technique. A pity. Of course, those same "team members" insisted on not sharing a single line of common code between client and server, even when there were perfectly NON-preprocessor based interfaces to thoroughly tested code. They didn't like "templates", either. In other words, I couldn't have written ANYTHING that the useless prats would use. Heck, they invented (retarded, buggy) containers of their own, even though using 'stl' was mandated. How many new (and broken) versions of std::basic_string< > does the world really need?
You either recognize the usefulness in getting the computer to do your work for you, or you don't. I'd much rather type it once and let the compiler paste it together ten different ways, than personally type it ten different ways and then keep going back to make updates to ten different bodies of code whenever a new addition needs to be made. That's the work I make CPP do.
When it has come right down to it, CPP is easier to do the same things with than C++. Especially when you start into the "advanced" template techniques.
Of course, the big difference here is, CPP has "always" been around. Most versions of C++ are still trying to follow the "rules" that were laid out for them. There is still lots of perfectly valid C++ code that some compilers will build, and others will not.
Actually Visual Studio (even .net) chokes on my macros (and BOOST macros) a LOT due to the fixed internal pools and buffering. Usually this can be fixed by disabling 'incremental compile' and 'precompiled headers'. Their little 'time saving' steps are bugged. But hey, it's a Microsoft product. You expect bugs.
espritch
12th March 2004, 11:00 PM
I like Java. I think it is well thought out language despite inheriting some awkward syntax from C++.
P.S. I was unable to vote. I get an error saying my session is invalid. This seems to happen a lot for me with poles.
Yahweh
12th March 2004, 11:28 PM
Originally posted by espritch
I like Java. I think it is well thought out language despite inheriting some awkward syntax from C++.
P.S. I was unable to vote. I get an error saying my session is invalid. This seems to happen a lot for me with poles.
Do you enable cookies? If so, do you browse the board with cookies?
If you dont enable your cookies, your PHP Session variables will expire which will throw off voting and posting. (Sometimes, the cookies or PHP Sessions will spontaneously disappear out of existence, its happened to me a few times.)
To revamp your PHP Session, just log into your account again and you ought to be able to vote.
Oh, one more thing... ASP is so much better than PHP!
Earthborn
12th March 2004, 11:55 PM
Originally posted by evildave
#define _z ;
Now you can end every line with '_z', if you like.Can you also make possible to end every line with a carriage return, except when it is preceded by an underscore?Though this one used to be - and should be Earthborn's favorite.
http://www0.us.ioccc.org/1990/dds.cAaargh... Not exactly. :)
I usually use write programs (for fun, not profit) with lots of whitespace and indentation and stuff and only compact it when I want to impress others on how short it is.
Cecil
13th March 2004, 12:23 AM
If you see programming as an art, give Piet (http://www.dangermouse.net/esoteric/piet.html) a try.
If you just like monkeying around, try Ook (http://www.dangermouse.net/esoteric/ook.html) .
If you're a poet at heart, Haifu (http://www.dangermouse.net/esoteric/haifu.html) is for you.
Whenever (http://www.dangermouse.net/esoteric/whenever.html) is for the scatterbrained type.
If you only think linearly, then you need to use Reverse (http://www.geocities.com/brianscsmith/reverse.html).
If you only think two-dimensionally, then you want Orthogonal (http://www.muppetlabs.com/~breadbox/orth/orth.html) or maybe Wierd (http://catseye.mine.nu:8080/projects/wierd/doc/wierdspec.txt).
If you know anything about lambda calculus, you might understand Unlambda (http://www.eleves.ens.fr:8080/home/madore/programs/unlambda/#what_is)
bjornart
13th March 2004, 03:43 AM
Sheesh, Cecil. Those are all wussy languages when compared with Whitespace (http://compsoc.dur.ac.uk/whitespace/)
I work mostly in C++, but I'd be happy to rewrite the whole stupid system in Java if they'd just see the light and allocate funds for it.
I'm not religious about it, different languages for different purposes, but C# is an abomination from the big $atan himself.
evildave
13th March 2004, 08:55 PM
Originally posted by Earthborn
Can you also make possible to end every line with a carriage return, except when it is preceded by an underscore?Aaargh... Not exactly. :)
I usually use write programs (for fun, not profit) with lots of whitespace and indentation and stuff and only compact it when I want to impress others on how short it is.
It is a BASIC interpreter.
Kopji
13th March 2004, 09:36 PM
Logo
We used to sell TI 9-4A's to the school districts on the Rez (I think I remember that Texas Instrument PC right). Must've been 1982 or so. Had Logo that came on a plug in cartridge and you could save programs to a cassette deck.
Cool for introducing kids to programming. An don't ask me any programming questions, I've long forgotten...
My second job (1977?) was helping write assembly code for an RCA CDP 1802 cpu. Something about all the commands being the same length worked for us. (Designing test equipment)
I worked with an Evil Programmer late into the night on weekends, weekdays, and holidays.
Found out much later the 1802 was a Silicon on Sapphire device, used on the Voyager spacecraft and still flying. Woo woo.
toddjh
13th March 2004, 11:01 PM
Originally posted by Kopji
Logo
We used to sell TI 9-4A's to the school districts on the Rez (I think I remember that Texas Instrument PC right). Must've been 1982 or so. Had Logo that came on a plug in cartridge and you could save programs to a cassette deck.
Yay! I had a TI-99/4A when I was 6. Damn cool hobbyist computer for the time. My dad and I learned BASIC on it together, and it had a speech synthesizer module that was way ahead of its time and tons of fun for a kid to play with. Schools around here all had Apple II permutations, which were much less interesting. :)
Jeremy
the_ignored
15th March 2004, 03:51 AM
Anyone here ever hear of Eiffel (http://www.eiffel.com/downloads/)?
All I remember, is how to make (http://www.99-bottles-of-beer.net/e.html#Eiffel-(object-orientated)) something:
ex)
!!shelf.make (99) <~~shelf being an object class you've defined and now you're making 99 of them.
What's really stupid, do you know how !!shelf.make (99) is "pronounced" verbally?
Bang Bang, shelf dot make 99
Bang Bang? Bang, Bang?!
Stupid useless language. After taking that course, I never even heard of it again!
Took it a few years ago, and don't remember a damned thing about it...
It's Java and VB 6 for me...and when I get time, some practice in MySQL database stuff.
Beerina
16th March 2004, 11:55 AM
Originally posted by UserGoogol
Different languages for different purposes. But Lisp is probably the best of them all.
That's my feeling, too, and I haven't programmed regularly in Lisp for 12 years. (3 years full time professional of Lisp!)
It's nice to not have to waste time designing structures to hold varied data types. It's what the language of the Internet should have been. Computers are so insanely powerful now, even things like word processors with large documents can be handled in interpreters ("eval"), to say nothing of compiled speeds. Like any other programs, only intense computation or 3D games need such horsepower beyond an interpreter.
toddjh
16th March 2004, 12:20 PM
Originally posted by Beerina
Like any other programs, only intense computation or 3D games need such horsepower beyond an interpreter.
Not even 3D games, if they have access to a low-level library like DirectX. Minus JIT compilation times, a well-written program in a good interpreted/managed language like VB.NET or C# is generally 90-95% as fast as an equivalent program compiled to native code, and smart compilers are getting better and better all the time.
There will always be a demand for low-level languages to write compilers and number-crunchers and applications that need to interface directly with low-level hardware. But for most real-world applications, a high-level language is just fine, and vastly increases productivity.
Jeremy
Abdul Alhazred
16th March 2004, 12:27 PM
Originally posted by Cecil
If you know anything about lambda calculus, you might understand Unlambda (http://www.eleves.ens.fr:8080/home/madore/programs/unlambda/#what_is)
Jeez Louise! And I thought Intercal was bad. :D
Dymanic
16th March 2004, 12:55 PM
Originally posted by Beerina
Like any other programs, only intense computation or 3D games need such horsepower beyond an interpreterMost modern Lisp implementations do compile to native code.
Paul C. Anagnostopoulos
16th March 2004, 01:43 PM
It is wrong to use a leading zero to indicate octal.
It is wrong to design an object-oriented extension to a language based on whether it can be done with the preprocessor.
It is wrong to use whitespace to indicate structuring.
It is wrong not to have a true boolean type.
It is wrong not to have functions be a first-class data type.
It is wrong not to have a real macro facility.
It is wrong to confuse definition and declaration.
It is wrong to have whitespace be meaningful in regular expression literals.
It is wrong to have more than one kind of character string literal, and three or more is diabolical.
~~ Paul
Atlas
16th March 2004, 02:31 PM
Originally posted by Paul C. Anagnostopoulos
It is wrong to use a leading zero to indicate octal.
It is wrong to design an object-oriented extension to a language based on whether it can be done with the preprocessor.
It is wrong to use whitespace to indicate structuring.
It is wrong not to have a true boolean type.
It is wrong not to have functions be a first-class data type.
It is wrong not to have a real macro facility.
It is wrong to confuse definition and declaration.
It is wrong to have whitespace be meaningful in regular expression literals.
It is wrong to have more than one kind of character string literal, and three or more is diabolical.
~~ Paul Paul that was only 9. You should add 1 positive one like:
Honor thy Father and Mother
Yahweh
16th March 2004, 05:31 PM
Originally posted by Paul C. Anagnostopoulos
It is wrong to use whitespace to indicate structuring.
Blasphemy, Paul, blasphemy...
Here is an example of a simple database routine in ASP/ADO with whitespace...
if Session("Username") <> "" then
response.redirect "default.asp"
end if
Username = request("Username")
Password = request("Password")
PrevURL = request("p")
if PrevURL = "" then
PrevURL = "default.asp"
end if
if Username <> "" and Password <> "" then
Set conn = Server.CreateObject("ADODB.Connection")
conn.open DSNName
Set rs = Server.createobject("ADODB.recordset")
rs.Open "SELECT * from RegisteredUsers WHERE Username = '" & Username & "' AND Password = '" & Password & "'",conn,3,3
if not rs.EOF then
Session("Username") = rs("Username")
Session("Timezone") = rs("Timezone")
Session("Timeformat") = rs("Timeformat")
Session("Dateformat") = rs("Dateformat")
if Session("TimeFormat") = "Default" then
Session("LastVisit") = FormatDateTime(Now, vbLongTime)
else
Session("LastVisit") = FormatDateTime(Now, vbShortTime)
end if
ID = rs("ID")
Session("ID") = ID
if rs("Admin") = Session("Username") then
Session("Admin") = rs("Admin")
else
Session("Admin") = ""
end if
if rs("Moderator") = Session("Username") then
Session("Moderator") = rs("Moderator")
else
Session("Moderator") = ""
end if
sql = "select LastLogin from RegisteredUsers where ID = " & ID
Set rs = Server.CreateObject("ADODB.RecordSet")
rs.Open sql, conn, 3, 3
if not rs.eof then
rs("LastLogin") = Now
rs.update
rs.close
else
LoginFailed = True
end if
LoginFailed = False
else
LoginFailed = True
end if
conn.close
else
LoginFailed = True
end if
Here is the same routine without whitespace...
if Session("Username") <> "" then response.redirect "default.asp" end if
Username = request("Username")
Password = request("Password")
PrevURL = request("p")
if PrevURL = "" then PrevURL = "default.asp" end if
if Username <> "" and Password <> "" then
Set conn = Server.CreateObject("ADODB.Connection")
conn.open DSNName
Set rs = Server.createobject("ADODB.recordset")
rs.Open "SELECT * from RegisteredUsers WHERE Username = '" & Username & "' AND Password = '" & Password & "'",conn,3,3
if not rs.EOF then
Session("Username") = rs("Username")
Session("Timezone") = rs("Timezone")
Session("Timeformat") = rs("Timeformat")
Session("Dateformat") = rs("Dateformat")
if Session("TimeFormat") = "Default" then Session("LastVisit") = FormatDateTime(Now, vbLongTime) else Session("LastVisit") = FormatDateTime(Now, vbShortTime) end if
ID = rs("ID")
Session("ID") = ID
if rs("Admin") = Session("Username") then Session("Admin") = rs("Admin") else Session("Admin") = "" end if
if rs("Moderator") = Session("Username") then Session("Moderator") = rs("Moderator") else Session("Moderator") = "" end if
sql = "select LastLogin from RegisteredUsers where ID = " & ID
Set rs = Server.CreateObject("ADODB.RecordSet")
rs.Open sql, conn, 3, 3
if not rs.eof then
rs("LastLogin") = Now
rs.update
rs.close
else LoginFailed = True end if
LoginFailed = False else LoginFailed = True end if
conn.close else LoginFailed = True end if
Next you'll wanna tell me there is no point in leaving comments...
Paul C. Anagnostopoulos
16th March 2004, 05:43 PM
A thousand pardons, Yahweh. I should have said:
It is wrong to use whitespace as the only method of indicating structure.
I was referring to such abominations as Python.
~~ Paul
Yahweh
16th March 2004, 06:21 PM
Originally posted by Paul C. Anagnostopoulos
A thousand pardons, Yahweh. I should have said:
It is wrong to use whitespace as the only method of indicating structure.
I was referring to such abominations as Python.
~~ Paul
I see, the seeds of doubt have been lifted, the clouds of confusion have cleared, I see the light... and I think it be a syntax error...
Paul C. Anagnostopoulos
16th March 2004, 06:40 PM
Your syntax was fine until you deleted that space. See that one there? The one between the other seven spaces? You deleted it by mistake. Changed the entire meaning of your program.
~~ Paul
Scot C. Trypal
16th March 2004, 07:57 PM
All these posts and I can find no mention of FORTRAN... I must have done something horribly wrong in a past life.
Anybody else remember Logo?
Barely, I think. I remember using Dr. Logo (the same?), late into the night as a kid.
It was like a computerized etch-a-sketch, but fun and with an unwieldy programming language, and it used the Asteroid ship to represent the “pen”, right?
Also, are there no lazy folks here? I’ve developed a nasty matlab habit, and haven’t opened my C++ editor for years.
Abdul Alhazred
16th March 2004, 08:42 PM
Originally posted by Scot C. Trypal
All these posts and I can find no mention of FORTRAN... I must have done something horribly wrong in a past life.
Maybe so. I haven't done any FORTRAN since the early '80s. I don't doubt that there's still some out there, but is there any new development in it?
COBOL, on the other hand...
But no, that's of the Devil. :D
Scot C. Trypal
17th March 2004, 05:56 AM
Maybe so. I haven't done any FORTRAN since the early '80s. I don't doubt that there's still some out there, but is there any new development in it?
Not really any new exciting breakthroughs in FORTRAN that I know of.
You’re right though; it's still here. It’s more of a problem of stumbling upon the code in something like the controller for valve #5 in red dye #3’s 20-year-old distillation tower. You know the author is long dead, but, FORTRAN, it will not die.
Paul C. Anagnostopoulos
17th March 2004, 06:58 AM
I think Fortran is still popular. There are so many libraries written for it.
Don't forget PL/I. Now there was a horrendous mess. But I loved it.
~~ Paul
Wudang
17th March 2004, 10:01 AM
I was never that fond of PL/I until I had to use COBOL the last couple of years. I spent a while with PL/AS which was PL/I based but oriented towards systems programming. You could break to assembler any time which was neat.
Walter Wayne
17th March 2004, 11:17 PM
With regards to FORTRAN, ask physics students about it, and maybe some engineers. It is still used for numerical modelling (mainly due to the extensive libraries for linear algebra). IIRC it got an "update" to the standard in the late 90's (just checked it was 1990 - FORTRAN 90).
Could some physics student remind me if it now has a complex data type? I might be out of my mind but I thought that was one element added. (Also checked, it appears FORTRAN 90 does support COMPLEX data type)
Walt
smalltlalk_2k
18th March 2004, 11:32 AM
10110101000101010101010111010010101010001111110101 00101010000000010111111011101010010110101010100101 00100010101001010101010011110010101010100101010010 1
Atlas
18th March 2004, 11:45 AM
Originally posted by smalltlalk_2k
10110101000101010101010111010010101010001111110101 00101010000000010111111011101010010110101010100101 00100010101001010101010011110010101010100101010010 1 Yah smalltalk,
We've heard that before. That doesn't make it true.
c4ts
18th March 2004, 09:24 PM
Fools. Only AREXX is the One, True, Programming language!
Leif Roar
19th March 2004, 10:30 AM
What? No mention of Ada yet?
Woe unto thee of weak type and informal grammar - thy programs will be buggy and bloated, and will run but poorly, and thy source code will be one unholy mess - yea, verily as unreadable as APL or Perl. Thou will write code in vain, and errors which could have been detected by the compiler will not be, but will lingering like a gangrenous sore in the innards of thy product, only to blossom into a lily of death once installed at thine customer's site. Woe unto thee who scorns the true light of Ada and prays at a lesser language's compiler. Yea, woe will be thine and so will be sleepless nights and hours uncountable as the stars in the sky will thou spend in the debugger.
evildave
19th March 2004, 01:44 PM
There always be lint.
http://www.splint.org/
Colloden
19th March 2004, 02:27 PM
How about Brainf*ck (http://www.muppetlabs.com/~breadbox/bf/) ?
Abdul Alhazred
19th March 2004, 03:03 PM
Originally posted by Colloden
How about Brainf*ck (http://www.muppetlabs.com/~breadbox/bf/) ?
Here is a Turing-complete programming language with one instruction:
One byte is defined as however many bits are needed to address any location in the memory space. The number of bits in a memory location is identical to a byte so defined.
The memory space is large "enough".
I/O is done by memory mapping. That makes I/O not a programming language issue.
The initial program load is whatever it has to be (wave hands).
The instruction pointer starts at location one. Read four bytes as the argument, as follows:
byte 1 == address of first argument of NAND operation.
byte 2 == address of second argument of NAND operation.
byte 3 == address of result of NAND operation.
byte 4 == address of next instruction. If zero, stop.
Leif Roar
19th March 2004, 03:24 PM
Of course, the war over programming languages is hardly the ultimate Holy War. It's not even the penultimate one (that's the War over OSes.) The ultimate Holy War is of course "Emacs vs. Vi"
Wudang
19th March 2004, 04:03 PM
What is this "emacs" of which you speak?
Paul C. Anagnostopoulos
19th March 2004, 05:47 PM
Leif said:
The ultimate Holy War is of course "Emacs vs. Vi"
Are you telling me that the Church of vi is not empty?
~~ Paul
Beleth
20th March 2004, 12:37 AM
Originally posted by Paul C. Anagnostopoulos
Are you telling me that the Church of vi is not empty?No, because I happen to be fond of my wrist tendons.
And everything I've had to program lately has been done in Perl.
© 2001-2009, James Randi Educational Foundation. All Rights Reserved.
vBulletin® v3.7.7, Copyright ©2000-2012, Jelsoft Enterprises Ltd.