POV-Ray : Newsgroups : povray.off-topic : GOTO Server Time
3 Sep 2024 23:23:57 EDT (-0400)
  GOTO (Message 21 to 30 of 36)  
<<< Previous 10 Messages Goto Latest 10 Messages Next 6 Messages >>>
From: Darren New
Subject: Re: GOTO
Date: 16 Oct 2010 16:58:22
Message: <4cba11ee@news.povray.org>
Warp wrote:
>   By the way, I honestly wonder what's the "proper" way of doing that
> in Java, given that Java has exceptions and no scope-bound lifetime of
> objects. 

try {
handle = open(...);
} finally {
if (handle != null) handle.close();
}

Even uglier because you obviously have to declare the handle outside the 
block, check to see if the assignment worked, etc.

 > Do you always have to follow file handle creation with a 'try'
> block to guard against exceptions? Or is there some other trick to make
> such code exception-safe?

try/finally is what you use for making code exception safe.

>   (I understand that in C# this is handled with a 'using' block, which
> automatically and immediately disposes of objects when the block is
> exited. Is that the proper way of making file handles exception-safe
> there?)

Yep. You're basically supposed to put anything with a "Dispose" method 
inside a using block. (Well, unless you're assigning it to something more 
global, etc.)  More elegant than Java, but certainly not elegant, especially 
since it's not always obvious what classes have a Dispose method without 
reading the documentation, so it's easy to miss something if you're working 
with a new library.

-- 
Darren New, San Diego CA, USA (PST)
   Serving Suggestion:
     "Don't serve this any more. It's awful."


Post a reply to this message

From: Darren New
Subject: Re: GOTO
Date: 16 Oct 2010 17:00:11
Message: <4cba125b$1@news.povray.org>
Darren New wrote:
> and everything in between would be unable to overwrite it or 
> copy it or whatever (outside of, of course, passing it to subroutines, 
> etc).

Well, not quite. I mean, there are a lot of rules making it usable, but 
they're the obvious rules. (You can overwrite the value with a newly 
allocated value if you dispose of the old value in the same routine, etc.)

-- 
Darren New, San Diego CA, USA (PST)
   Serving Suggestion:
     "Don't serve this any more. It's awful."


Post a reply to this message

From: nemesis
Subject: Re: GOTO
Date: 16 Oct 2010 18:50:00
Message: <web.4cba2b4d8a3e2d77a197654e0@news.povray.org>
Darren New <dne### [at] sanrrcom> wrote:
> Yeah, I was trying to remember some of the others. Something perl-like,
> certanily (python, Perl, bash, Tcl, etc).

python, perl and tcl are very unlike each other despite the scripting moniker.
While I dig python better for the crystal-crisp syntax and iteration constructs,
perl is much more formidable as far as plain linguistic flexibility goes... it
truly is a marvel to behold in all of its C, shell, Lisp, forth summarizing of
ideas goes...


Post a reply to this message

From: Darren New
Subject: Re: GOTO
Date: 16 Oct 2010 19:48:10
Message: <4cba39ba@news.povray.org>
nemesis wrote:
> Darren New <dne### [at] sanrrcom> wrote:
>> Yeah, I was trying to remember some of the others. Something perl-like,
>> certanily (python, Perl, bash, Tcl, etc).
> 
> python, perl and tcl are very unlike each other despite the scripting moniker.

Fairly so, yes. But the concepts of a "scripting language" (i.e., the 
primary data structure being a hashtable, the idea that "evaluating a 
definition" is pretty much what creates code rather than strictly 
compilation, the baroque scoping rules, etc) is what's more important than 
the fact that (for example) regex is a literal in Perl and not in the others.

> truly is a marvel to behold in all of its C, shell, Lisp, forth summarizing of
> ideas goes...

Errr, Perl has something to do with FORTH?  You'll have to clarify that one, 
because, like, it really doesn't, as far as I can tell.


-- 
Darren New, San Diego CA, USA (PST)
   Serving Suggestion:
     "Don't serve this any more. It's awful."


Post a reply to this message

From: nemesis
Subject: Re: GOTO
Date: 17 Oct 2010 07:00:01
Message: <web.4cbad67a8a3e2d77a197654e0@news.povray.org>
Darren New <dne### [at] sanrrcom> wrote:
> nemesis wrote:
> > Darren New <dne### [at] sanrrcom> wrote:
> >> Yeah, I was trying to remember some of the others. Something perl-like,
> >> certanily (python, Perl, bash, Tcl, etc).
> >
> > python, perl and tcl are very unlike each other despite the scripting moniker.
>
> Fairly so, yes. But the concepts of a "scripting language" (i.e., the
> primary data structure being a hashtable, the idea that "evaluating a
> definition" is pretty much what creates code rather than strictly
> compilation, the baroque scoping rules, etc) is what's more important than
> the fact that (for example) regex is a literal in Perl and not in the others.

regex is a literal in ruby too.  I also like perl scoping with my and our. :)

> > truly is a marvel to behold in all of its C, shell, Lisp, forth summarizing of
> > ideas goes...
>
> Errr, Perl has something to do with FORTH?  You'll have to clarify that one,
> because, like, it really doesn't, as far as I can tell.

like forth, it doesn't need to operate on named arguments, which is taken then
to be the first in the "stack"... :)


Post a reply to this message

From: Warp
Subject: Re: GOTO
Date: 17 Oct 2010 08:57:35
Message: <4cbaf2bf@news.povray.org>
Darren New <dne### [at] sanrrcom> wrote:
> The destructor semantics is one of the things I think C++ really did get 
> just right.

  The proper name for that mechanism would be "RAII" (which might be
somewhat of a misnomer, as it doesn't fully express what it means).

  (In principle RAII is not incompatible with garbage collection, so
conceivably you could have both in the same language.)

  According to wikipedia, C++ is not the only language using RAII, and
mentions Ada as another one. I didn't know that.

-- 
                                                          - Warp


Post a reply to this message

From: Darren New
Subject: Re: GOTO
Date: 17 Oct 2010 13:00:00
Message: <4cbb2b90@news.povray.org>
nemesis wrote:
> like forth, it doesn't need to operate on named arguments, which is taken then
> to be the first in the "stack"... :)

Uh, OK. That's, like, the absolute least important bit of FORTH there, but 
OK. :-)  I think that's more shell syntax than FORTH syntax, really.

-- 
Darren New, San Diego CA, USA (PST)
   Serving Suggestion:
     "Don't serve this any more. It's awful."


Post a reply to this message

From: Darren New
Subject: Re: GOTO
Date: 17 Oct 2010 13:26:03
Message: <4cbb31ab$1@news.povray.org>
Warp wrote:
> Darren New <dne### [at] sanrrcom> wrote:
>> The destructor semantics is one of the things I think C++ really did get 
>> just right.
> 
>   The proper name for that mechanism would be "RAII" (which might be
> somewhat of a misnomer, as it doesn't fully express what it means).

I think the two are separate, but "RAII" is the best (maybe even "intended") 
way to use the C++ destructor semantics. Certainly the semantics don't 
change if you screw up your RAII. :-)

>   (In principle RAII is not incompatible with garbage collection, so
> conceivably you could have both in the same language.)

Indeed. Especially if you use something like reference counting and deal 
with circular references specially or something. Unfortunately, the fastest 
garbage collectors are the ones that never touch the garbage, so it's hard 
to do this well without having basically a separate heap for objects with 
non-memory destructors, which I think is what we'll eventually start seeing 
in some of these run-time implementations, if we don't start seeing GC-smart 
operating systems first.  (And I'd even count Erlang in that latter 
categorization, since all interaction outside the Erlang semantics goes thru 
a "port" kind of construct rather than a function call kind of construct.)

>   According to wikipedia, C++ is not the only language using RAII, and
> mentions Ada as another one. I didn't know that.

I think that's ... stretching it a bit. Sounds like Ada folks trying to 
convince C++ folks they should switch or something. :-)

Ada is very non-orthogonal in its data structures (even more so than C++). 
Objects are basically declared as "records with a vtable" or so, and if your 
data type isn't a type of record (in the Pascal/Algol sense of the word, or 
what C would call a struct), then you don't get to make it an object.

Ah. They're called "controlled types."

http://www.adaic.org/docs/95style/html/sec_9/9-2-3.html

Basically, an object type that inherits from Ada.Finalization.Controlled. 
Inheriting from that type gives you three methods: Initialize, Finalize and 
Adjust. Finalize is like the destructor, and Adjust is sort of like a 
copy/assignment constructor, only more limited. (When you assign to a 
controlled type, it copies all the hardware bits, then invokes Adjust on the 
copy. You don't get to change what you assigned *from*, because that would 
be confusing. Use a procedure with two in/out arguments for that. :-)

However, this only applies to objects derived from Controlled. It doesn't 
work with strings, arrays, any of the built-in collections, files, tasks, 
loadable packages, pointers, etc etc etc. Ada is really pretty 
non-orthogonal in that sense. You can't mix and match. (Yes, that sucks. :-)

I.e., much like you can't have constructors and destructors on pointers or 
integers in C++, except even for some very complicated types in Ada.

Note that any type can be declared "limited" too, which basically means the 
assignment operator is private. A record that can do inheritance (i.e., that 
has a vtable) is called a "tagged type". In case you get interested and read 
some of the following pages. :-)  Note that "class type X" means "X and all 
its descendants" as opposed to "type X" which means just type X. Declaring a 
procedure with an argument that is a class type is how you get run-time 
dynamic inheritance-based dispatch as opposed to overloading.  The "with 
private" declaration is like declaring something "struct xyz;" in C or C++. 
A "protected" type is basically a monitor in the multitasking definition of 
the word.

Blah'goop is a way of getting the goop property or type out of the blah 
variable or type. So myarray'length, or mytaggedtype'parent, or 
localvariable'address (&localvariable) or something like that.

Ada has some very unusual yet precise terminology. It's fun to read a 
sentence talking about a controlled atomic volatile protected limited class 
type and have an idea of what that means. ;-)

-- 
Darren New, San Diego CA, USA (PST)
   Serving Suggestion:
     "Don't serve this any more. It's awful."


Post a reply to this message

From: Warp
Subject: Re: GOTO
Date: 17 Oct 2010 14:34:37
Message: <4cbb41bd@news.povray.org>
Darren New <dne### [at] sanrrcom> wrote:
> >   (In principle RAII is not incompatible with garbage collection, so
> > conceivably you could have both in the same language.)

> Indeed. Especially if you use something like reference counting and deal 
> with circular references specially or something.

  What I meant is that, for example in C++, it's possible to have value
semantics for objects as well as reference (well, pointer) semantics for
objects, and these can be kept pretty much separate. Then you can have
RAII (iow. scope-based lifetime) semantics on the objects and GC on the
references. There are, in fact, GC engines for C++ which work like this
(basically, anything you allocate dynamically with 'new' can be GC'd,
while anything you allocate without it uses regular RAII semantics).

  On a different note, one example where I think the RAII mechanism is
better than the Java-style GC mechanism is that RAII allows you to
implement copy-on-write semantics (ie. "lazy copying") for objects.
In other words, if you have some object with potentially lots of data,
and you want to use copy semantics for it (ie. if you assign the object
to another, the latter gets a copy of the data rather than sharing the
data), copy-on-write makes the copying lazily, only if needed (ie. only
if one of the copies tries to modify the data).

  For instance, assume that std::string used copy-on-write (which it does
in some implementations). If you write this:

    std::vector<std::string> strings(1000, "hello there");

you will have a vector of 1000 strings, each one with the value "hello
there". However, the actual "hello there" data is shared among all the
strings and hence stored in memory only once (which may become a significant
saving if it would be kilobytes or megabytes of data instead of just 11
characters). However, if you now do something like:

    strings[250] += ", world";

only the 251st string in the vector will be converted to "hello there, world"
rather than all of them. The rest of the string will still share that one
and same data, and only the 251st string will now have its own copy of the
data, with more data appended.

  What happened there is that the 251st string made a deep-copy of the data
before modifying it, thus preventing any of the other strings from changing.

  Of course if you now modify it again:

    strings[250] += "!";

it will *not* perform a needless deep-copy of the data because the current
data is not shared. In other words, it will deep-copy the data only when
needed.

  And most importantly, it will do that completely transparently. You can't
see that from the outside. From the outside std::string simply has copy
semantics and that's it. You could compile the program with a different
implementation of std::string which does not use CoW, and it would still
work the same (except, obviously, now consuming more memory).

  Of course CoW requires reference counting of the data (or, more precisely,
it needs a way to tell if the data is being shared or not). I don't know
how you would do that in Java (transparently, or at all).

  This is possible transparently in C++ because of RAII: When objects are
created, copied, assigned and destroyed, you can specify what happens.
This allows you to keep a reference count on the data handled by the class.

  (And note that I'm not saying there aren't advantages with a GC system
like the one in Java, including efficiency benefits in some situations.)

-- 
                                                          - Warp


Post a reply to this message

From: Darren New
Subject: Re: GOTO
Date: 17 Oct 2010 15:10:12
Message: <4cbb4a14$1@news.povray.org>
Warp wrote:
> Darren New <dne### [at] sanrrcom> wrote:
>> Indeed. Especially if you use something like reference counting and deal 
>> with circular references specially or something.
> 
>   What I meant is that,

Oh, I see. Yes, I guess that would work. Probably an excellent way to do it, 
especially if you store enough info about things that you can do compacting 
collections.

>   On a different note, one example where I think the RAII mechanism is
> better than the Java-style GC mechanism is that RAII allows you to
> implement copy-on-write semantics (ie. "lazy copying") for objects.

I understand what you're saying, but this is a bad example for Java because 
that's exactly how it would work in Java, because strings are immutable, so 
your "+=" returns a brand new string. :-)  That's why Java has a 
StringBuilder as well as a String.

>   Of course CoW requires reference counting of the data (or, more precisely,
> it needs a way to tell if the data is being shared or not). I don't know
> how you would do that in Java (transparently, or at all).

Very difficult in Java to think of a way, offhand. I don't think you can 
overload pure assignment in C#, so I don't think you could do the same sort 
of thing there easily either.

>   This is possible transparently in C++ because of RAII: When objects are
> created, copied, assigned and destroyed, you can specify what happens.

I think it's more because you can overload the assignment operator, not the 
RAII as such. Maybe you count that as part of RAII.

-- 
Darren New, San Diego CA, USA (PST)
   Serving Suggestion:
     "Don't serve this any more. It's awful."


Post a reply to this message

<<< Previous 10 Messages Goto Latest 10 Messages Next 6 Messages >>>

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.