What other languages use the same data model as Python?

  • Thread starter Steven D'Aprano
  • Start date
G

Gregory Ewing

harrismh777 said:
'C' is still the best high-level language on that processor.

Some would argue that C is actually better than assembler these
days, because modern architectures are so freaking complicated
that it takes a computer to figure out the best instruction
sequence. :-(
 
C

Chris Angelico

Some would argue that C is actually better than assembler these
days, because modern architectures are so freaking complicated
that it takes a computer to figure out the best instruction
sequence. :-(

I use C to hint to the compiler as to what I'd like it to write a
program to do. It does all the writing, I just make some vague
suggestions - which it's free to ignore if it chooses. GCC and me, we
get along jess fine...

ChrisA
 
G

Gregory Ewing

harrismh777 said:
That is the $10,000,000 dollar problem... how to
extricate ourselves from the von Neumann processor. *Everthing* comes
down to that... its hilarious to hear folks talk about lambda the
ultimate (especially those guys on Lambda the Ultimate) when there is no
such thing until such time as we have lambda the hardware architecture.

I think there are fundamental problems that go beyond the
issue of hardware design. It's easy to reason about a program
that does things one step at a time, much harder when lots
of things are happening at once. Whether you express the
program using lambda calculus or a Turing machine doesn't
change that fact.
 
G

Gregory Ewing

John said:
A reasonable compromise would be that "is" is treated as "==" on
immutable objects.

That wouldn't work for tuples, which can contain references
to other objects that are not immutable.
 
G

Gregory Ewing

harrismh777 said:
'C' does provide for pointers which are used by all 'C'
programmers to firmly provide pass-by-reference in their coding

Yes, but when they do that, they're building an abstraction
of their own on top of the facilities provided by the C
language. C itself has no notion of pass-by-reference. If
it did, the programmer would be able to use it directly
instead of having to insert & and * operators himself.
 
H

Hans Georg Schaathun

It's not clear to me that references are any more abstract
: than objects, or to put it another way, that objects are
: any less abstract than references.
:
: After all, in normal Python usage you never actually
: *see* an object

Sure, but you can refer directly to objects, pass objects around,
and refer to individual objects. This is abstract in the sense
that it is far removed from the memory representation. However,
the concept of a reference appears only when you explain how objects
are handled (semantics). You cannot reference nor manipulate a
reference in python, and that IMHO makes them more abstract.
 
M

Mel

John said:
A reasonable compromise would be that "is" is treated as "==" on
immutable objects.

I foresee trouble testing among float(5), int(5), Decimal(5) ...

Mel.
 
C

Chris Angelico

I foresee trouble testing among float(5), int(5), Decimal(5) ...

Define 'x is y' as 'type(x)==type(y) and
isinstance(x,(int,float,tuple,etc,etc,etc)) and x==y' then.

Chris Angelico
 
M

Mel

Tim said:
That is not an instance of passing an "int" by reference. That is an
instance of passing an "int *" by value. The fact that the parameter "a"
in BumpMe happens to be an address is completely irrelevent to the
definition of the parameter passing mechanism.

C has pass-by-value, exclusively. End of story.

Trouble with Turing-complete languages. If it can be done, you can convince
a Turing-complete language to do it -- somehow.

PL/I was the converse. All parameters were passed by reference, so with

some_proc (rocks);

the code in some_proc would be working with the address of rocks. If you
wanted pass-by-value you wrote

some_proc ((rocks));

whereupon the compiler would pass in by reference an unnamed temporary
variable whose value was the expression `(rocks)`. I suspect the compiler I
used avoided FORTRAN's troubles the same way. Your function could corrupt
*a* 4, but it wouldn't corrupt the *only* 4.

Mel.
 
S

Steven D'Aprano

[...]
  huh?   You have to be kidding. Why do you suppose we want it to be
open-sourced?   Use the force Luke, read the source.   If you really
want to know how Python is working you *must* dig down into the C code
which implements it.  The folks who document Python should be able to
tell us enough to know how to use the language, but to really 'know'
you need the implementation source.
Reading the CPython sources will show you how CPython works under the
hood, but it has nothing to do with how Python works. There are lots of
things that CPython does that "Python" does not. For instance, the GIL
is not a part of Python. Reference counting is not a part of Python.
Caching small integers and strings is not a part of Python. Why not read
the Jython sources instead of the CPython? It's the same language, after
all.

More importantly, Python need not be implemented at all. If you're stuck
on a desert island without electricity, you could simulate the effect of
running any arbitrary Python code merely by understanding the semantics
of high-level Python code, without caring the slightest about pointers at
the C implementation level, or bit flipping at the hardware level, or von
Neumann machines, or ref counting, or garbage collection, or any of a
million other implementation details. All you need understand is the
declared semantics of the language.

Surely I can't be the only one who sometimes tries to work out a tricky
bit of Python code by hand-simulating it on pencil and paper?
 
C

Chris Angelico

More importantly, Python need not be implemented at all. If you're stuck
on a desert island without electricity, you could simulate the effect of
running any arbitrary Python code merely by understanding the semantics
of high-level Python code...

http://xkcd.com/505/

Chris Angelico
 
S

Steven D'Aprano

Here is the thing that everyone forgets... all we have to work with
is a von Neumann processor. (same as EDVAC, ENIAC, the VIC20, etc).

Actually, this is incorrect. Most processors these days are hybrids
between that and either the Harvard or Modified Harvard architecture:

http://en.wikipedia.org/wiki/Modified_Harvard_architecture
http://en.wikipedia.org/wiki/Harvard_architecture
http://en.wikipedia.org/wiki/Von_Neumann_architecture

Assembler is still the best language on that processor.

Assembly is not "a" language, it is a generic term for dozens or hundreds
of different languages. But in any case, it's not clear what you mean by
"best language".

'C' is still the best high-level language on that processor.

C is better described as a high-level assembler, or a low-level language.
It is too close to the hardware to describe it as high-level, it has no
memory management, few data abstractions, and little protection.

Its silly to claim that one high-level language or another is better
suited to complex data abstraction... don't go there.

Surely you can't possibly mean that?

Surely you don't mean to tell us that the 1957 version of FORTRAN, or
unstructured BASIC, or early COBOL, are just as well suited to data
abstraction as (say) Haskell?

Many implementations of unstructured BASIC didn't even have arrays, only
character strings and integers.

Or (one of my personal favourites), Apple's Hypertalk? *Everything* is a
string in Hypertalk. I love Hypertalk, but good for data abstraction?
Don't make me laugh.

You should read Paul Graham on the Blub Paradox:

http://www.paulgraham.com/avg.html
 
N

Neil Cerutti

That's a quirk of CPython's boxed number implementation. All
integers are boxed, but there's a set of canned objects for
small integers. CPython's range for this is -5 to +256,
incidentally. That's visible through the "is" operator.
Arguably, it should not be.

But that's the sole purpose of the is operator. You either expose
those details, or you don't have an is operator at all.
 
S

Steven D'Aprano

Define 'x is y' as 'type(x)==type(y) and
isinstance(x,(int,float,tuple,etc,etc,etc)) and x==y' then.

`is` is supposed to be a *fast* operator, not even slower than equality
testing.
 
S

Steven D'Aprano

These definitions go all the way back before the 8080, or the 6502, 8
bit processors. Pass by reference has 'always' meant pass by using a
memory address (indirect addressing); a reference has always been a
memory pointer.

That's not a definition. That's an implementation.

Some day, we'll be using quantum computers without memory addresses, or
DNA computers, or some version of Babbage's Difference Engine (perhaps a
trillion of them in the volume of a match-head, tiny nano computing
devices... who knows?). Whatever it is, whether or not it has concepts of
"memory address" or "memory pointer", it will still be possible to
represent data indirectly via *some* mechanism.

If I call a function in C, and pass-by-value, the data's 'value' is
placed on the stack in a stack-frame, as a 'value' parm... its a copy
of the actual data in memory.
Correct.

If I call a function in C, and pass-by-reference, the data's 'address'

C doesn't do pass by reference. There is no way to declare a parameter to
a function as a by-reference parameter. You can only simulate it by hand,
by passing a pointer as data, pointing to what you *really* want as data,
and dereferencing it yourself. But the pointer itself is passed by value:
the address is copied onto the stack, just like any other piece of data
would be.

(The Python equivalent is to pass a list containing the object. If you
want call-by-reference behaviour without the convenience of language
support for it, you can have it.)

Pascal, on the other hand, does do pass by reference. If you declare a
"var" parameter, you then call the function with the variable you intend,
and the compiler handles everything:

function foo(x: int, var y: int): int;
begin
foo := x + y;
y := 0;
x := 0;
end;

a := 1;
b := 2;
c := foo(a, b);

After calling foo, the variable a remains 1, but the variable b is now 0.
The compiler is smart enough to figure out what to do behind the scenes
to make it all work.

We're not discussing what you, the coder, can do. Given any Turing-
complete language, you can (with sufficient cleverness and hard-work) do
anything any other Turing-complete language can do. We're discussing what
the compiler does, and for C, that is purely call by value.

Let me put it this way... old, unstructured BASIC has GOTOs and line
numbers, correct? And Python doesn't, correct? But you could write a
BASIC interpreter in Python, and call that interpreter from your Python
code... therefore Python has line numbers and GOTOs, no?

No. Of course not. We're discussing *language features*, and GOTO is not
a language feature of Python. Neither is call by reference a language
feature of C, or Python either for that matter, but it is a language
feature of VB and Pascal.

The only difference between the two scenarios is that writing a BASIC
interpreter is a tad harder than dereferencing a pointer, but that's just
a matter of degree, not of kind.
 
G

Grant Edwards

Yeah, that's kind-a funny, cause I'm one of the guys (old farts) that
helped define them....

I give up. You don't seem to understand the C language defintion or
what is commonly meant by "pass by reference".
 
G

Grant Edwards

Yes, but when they do that, they're building an abstraction
of their own on top of the facilities provided by the C
language.

I've pointed that out to him. He's talking about what _he_ does in
his program. We're talking about the C language definition and what
the compiler does.
C itself has no notion of pass-by-reference.

Exactly. C is pass by value.
If it did, the programmer would be able to use it directly
instead of having to insert & and * operators himself.

That's what I was trying to say, but probably not as clearly. The "&"
operatore returnas a _value_ that the OP passes _by_value_ to a
function. That function then uses the "*" operator to use that value
to access some data.
 
G

Grant Edwards

Yeah, Tim, I know... but that's my entire point in a nut-shell...
whether the language is pass-by-value or pass-by-reference has less to
do with how it is 'defined' (its mechanism--- indirection and stack)

No, whether the _language_ is pass by value or pass-by-reference has
_entirely_ to do with it's definition.
and more to do with how it is routinely used with the standard
features it provides--- in this case memory indirection--- as
pointers.

Now you're talking about how you can implement higher level constructs
using a language that doesn't directly implement such constructs. You
might as well say that C is a linked-list language like Lisp since you
can write a linked list implementation in C. If you said that you'd
be just as wrong as saying that C uses call-by-reference.
 
G

Grant Edwards

No, it's not. With call-by-name, the caller passes a
small function (known as a "thunk") that calculates the
address of the parameter. Every time the callee needs to
refer to the parameter, it evaluates this function.

This allows some neat tricks, but it's massive overkill for most
uses.

It also is a very good source of surprising bugs.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,276
Latest member
Sawatmakal

Latest Threads

Top