Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Message from discussion No exceptions?

Received: by 10.213.110.17 with SMTP id l17mr2075376ebp.23.1332863443573;
        Tue, 27 Mar 2012 08:50:43 -0700 (PDT)
X-BeenThere: candorlang@googlegroups.com
Received: by 10.52.88.105 with SMTP id bf9ls82575vdb.8.gmail; Tue, 27 Mar 2012
 08:50:42 -0700 (PDT)
Received: by 10.52.74.233 with SMTP id x9mr3000435vdv.15.1332863442823;
        Tue, 27 Mar 2012 08:50:42 -0700 (PDT)
Date: Tue, 27 Mar 2012 08:50:42 -0700 (PDT)
From: Bradley Meck <bradley.m...@gmail.com>
To: candorlang@googlegroups.com
Message-ID: <22414681.373.1332863442461.JavaMail.geo-discussion-forums@yncc6>
In-Reply-To: <CAEv2VfJr3CbL1REdzV=j_o+dF36RaQDCTF0mdsYbfBfXhD9hQA@mail.gmail.com>
References: <6855770.1152.1332516554265.JavaMail.geo-discussion-forums@ynlp3>
 <CAEv2VfLxL1jyRc0tk1ZNyY3XU5Baxas1iFVy+NMFuqTOmsZ9Jw@mail.gmail.com>
 <CAGkHjAVWhJgMcbie9mQmb=ZjYAOXHN=b6moN=fRz-n+4vR3Zhw@mail.gmail.com>
 <3597272.458.1332528580103.JavaMail.geo-discussion-forums@yncc6>
 <CAGkHjAXHKcCmNCVM-wmAPV3=DQvEzrjAG=P=y2qj2tOs9b2e9A@mail.gmail.com> <13115260.591.1332534450899.JavaMail.geo-discussion-forums@ynjk1>
 <CAEv2VfJr3CbL1REdzV=j_o+dF36RaQDCTF0mdsYbfBfXhD9hQA@mail.gmail.com>
Subject: Re: No exceptions?
MIME-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_371_30169597.1332863442458"

------=_Part_371_30169597.1332863442458
Content-Type: multipart/alternative; 
	boundary="----=_Part_372_19396901.1332863442458"

------=_Part_372_19396901.1332863442458
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Indeed, which is why I think for now we should stick to return values. I'm=
=20
not convinced that failure proof code that may have side effects on the=20
system is good, but it is one approach.

On Tuesday, March 27, 2012 3:30:23 AM UTC-5, Fedor Indutny wrote:
>
> I think you're just trying to apply existing design habbits to a new=20
> language.
>
> Handling return values works fine for C and may work fine for Candor too,=
=20
> though it needs to be proved by a practice. The pros of this method is th=
at=20
> you always know that code you're calling won't stop execution, which is=
=20
> good for failure-proof applications.
>
> Cheers,
> Fedor.
>
>
>
> On Sat, Mar 24, 2012 at 3:27 AM, Bradley Meck <bradley.m...@gmail.com>wro=
te:
>
>> For now return values are probably enough. In the future, an exception=
=20
>> handler stack might be more appropriate. This may be too intensive becau=
se=20
>> of handling multiple error handler trees (but is quite similar to domain=
s).
>>
>> thisCausesAnException(callback) {
>>   // explicit abort into an exception handler
>>   callback:abort({reason:'cause I said so'}, {multipleOk: true})
>> }
>>
>> doStuff() {
>>   readAFile(callback() {
>>     thisCausesAnException()
>>   } catches(e, x) {
>>     print('could not read the file')
>>     // implicit throw, up the error handling chain
>>     // akin to a rethrow
>>     abort(e)
>>   })
>> } catches(e) {
>>   print(e.reason);
>> }
>>
>> Just a brain dump. Though a while back I had an idea of 'throwing' into=
=20
>> functions, basically avoiding the error first problem of node by allowin=
g=20
>> functions to have exception handlers that could be called without ever=
=20
>> calling the function (causes uncaught exception handler to fire if the=
=20
>> function has no explicit exception handler). This would avoid error hand=
ler=20
>> overhead unless functions add them during invocation when a function can=
=20
>> handle errors, as well as have some sanity when just throwing up the sta=
ck.
>>
>> Cheers,
>> Bradley
>>
>>
>> On Friday, March 23, 2012 2:09:02 PM UTC-5, Tim Caswell wrote:
>>>
>>> Right, this is why I say to never use hard aborts for runtime errors,=
=20
>>> only for invalid configurations.
>>>
>>> And you're correct, we need a story for the more common runtime errors.=
=20
>>> C does this with return values and callback arguments.
>>>
>>> The problem with this C style is that it makes it easy to ignore errors=
.=20
>>>  If I forget to check the return value of a call then I'll never know i=
t=20
>>> didn't work.  Bad stuff will happen down the road and probably segfault=
 or=20
>>> just do nothing.
>>>
>>> Perhaps we could add a constraint on the system that return values can'=
t=20
>>> be ignored.  This is hard without static typing and static analysis, th=
e=20
>>> parser doesn't know if a function will return a value and the runtime i=
s=20
>>> just generated code, we don't want to add in runtime checking and=20
>>> introspection code at every function call.  So that idea probably won't=
=20
>>> work.
>>>
>>> A better convention is maybe an aspect oriented configuration in our=20
>>> libraries where you pass in the error handler to all object creation=20
>>> functions.  Then the library can report errors to this.  Add to this an=
=20
>>> aspect oriented resource manager and the concept of domains and you can=
=20
>>> register cleanup functions anytime a resource would need to clean if=20
>>> something down the line blew up.
>>>
>>> Just spouting off ideas.  If in doubt we can just take the simple route=
=20
>>> and require the programmer to check all return values and hope that's g=
ood=20
>>> enough.
>>>
>>>
>>>
>>> On Fri, Mar 23, 2012 at 1:49 PM, Bradley Meck <bradley.m...@gmail.com>w=
rote:
>>>
>>>> I would avoid hard abort(). libgmp last time I checked was doing=20
>>>> abort() after encountering errors, which made it prohibitively hard to=
 deal=20
>>>> with when you open up fds and cannot close them properly due to aborts=
. To=20
>>>> get around this you would need to spawn up a new thread and pass fds a=
round.
>>>>
>>>>
>>>> On Friday, March 23, 2012 12:06:37 PM UTC-5, Tim Caswell wrote:
>>>>
>>>>> I think hard exceptions (like failed asserts in C) are fine for thing=
s=20
>>>>> that are obviously programmer error (like wrong number or types of=20
>>>>> arguments).  in C these are caught by the compiler, but we don't have=
=20
>>>>> strict type checking in candor.  We need some sort of hard assert for=
 this.=20
>>>>>  I could build it into the candor.io library and implement it in C++.=
=20
>>>>> It would be nice if I had a way to get the stack trace, or at least t=
he=20
>>>>> line that threw the assert.
>>>>>
>>>>> But the other class of errors that you don't want crashing your serve=
r=20
>>>>> are invalid user input.  The way libuv (The C library behind nodejs a=
nd=20
>>>>> candor.io) handles these errors is to return a non-zero status on any=
=20
>>>>> function call that potentially can throw an error.  For async functio=
ns,=20
>>>>> there is a status property in the callback.  It's the responsibility =
of the=20
>>>>> programmer to check for this status code and them pull the actual err=
or=20
>>>>> message out of libuv using the error API.
>>>>>
>>>>> I've done something like this for candor.io.  It's not pretty, but=20
>>>>> seems to work ok.  The only sticky point is sync functions that retur=
n a=20
>>>>> value.  Where do I put the status code?  In lua this is done with mul=
tiple=20
>>>>> return values, but I don't think that's a feature we want to add to c=
andor=20
>>>>> (as much as I love it).
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> throw =3D (err) {
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>   global.prettyPrint(err)
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>   global.exit()
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> }
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> // Used to emit on errors when libuv badness happens
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> check =3D (status) {
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>   if (status) {
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>     throw(require('uv').=E2=80=8B=E2=80=8BlastError())
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>   }
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> }
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> ServerPrototype =3D {}
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> ServerPrototype.listen =3D (self, port, host, callback) {
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>   if (!host) host =3D "0.0.0.0"
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>   check(self.socket:bind(host, port))
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>   check(self.socket:listen(=E2=80=8B=E2=80=8B128, (status) {
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>     check(status)
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>     client =3D new ClientPrototype
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>     socket =3D Tcp.create()
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>     client.socket =3D socket
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>     check(self.socket:accept(=E2=80=8B=E2=80=8Bsocket))
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>     self.onConnection(client)
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>     check(socket:readStart((=E2=80=8B=E2=80=8Bnread, chunk) {
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>       if (nread =3D=3D -1) {
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>         err =3D require('uv').lastError()
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>         if (err.name =3D=3D "EOF") {
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>           client.onEnd()
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>         } else {
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>           throw(err)
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>         }
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>         return
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>       }
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>       if (nread > 0) {
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>         client.onData(chunk)
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>         return
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>       }
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>     }))
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>   }))
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> }
>>>>>
>>>>>
>>>>> On Fri, Mar 23, 2012 at 11:57 AM, Fedor Indutny <fe...@indutny.com>wr=
ote:
>>>>>
>>>>>> Bradley,
>>>>>>
>>>>>> Exceptions are good, but I'm considering Candor to be more like C,=
=20
>>>>>> than C++.
>>>>>>
>>>>>> As I know C works fine w/o exceptions, I'm open to introducing some=
=20
>>>>>> sort of `abort()` instruction, which will leave candor into C++ land=
.
>>>>>> Feedback is welcome!
>>>>>>
>>>>>> Cheers,
>>>>>> Fedor.
>>>>>>
>>>>>>
>>>>>>
>>>>>> On Fri, Mar 23, 2012 at 9:29 PM, Bradley Meck <bradley.m...@gmail.co=
m
>>>>>> > wrote:
>>>>>>
>>>>>>> In situations where you are extending a function/method in a way=20
>>>>>>> that could cause a need to throw an exception in other languages wh=
at is=20
>>>>>>> the idea for how to handle this?
>>>>>>>
>>>>>>> ```candor
>>>>>>> Rect =3D {
>>>>>>>   initialize: (self, w, h) {
>>>>>>>     self.w =3D w
>>>>>>>     self.h =3D h
>>>>>>>   }
>>>>>>> }
>>>>>>>
>>>>>>> Square =3D new Rect
>>>>>>> Square.initialize =3D (self, w, h) {
>>>>>>>    if (w !=3D=3D h)
>>>>>>>       // ?
>>>>>>>    Rect.initialize(self, w, h)
>>>>>>> }
>>>>>>> ```
>>>>>>>
>>>>>>> This example is naive, but it will come up in cases where an=20
>>>>>>> interface that originally did not have exceptions / didn't need cal=
lbacks=20
>>>>>>> to notify exception would suddenly need exceptions. Right now the o=
nly way=20
>>>>>>> to halt a large nesting of calls seems to have every return checked=
.
>>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>
>
------=_Part_372_19396901.1332863442458
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: quoted-printable

Indeed, which is why I think for now we should stick to return values. I'm =
not convinced that failure proof code that may have side effects on the sys=
tem is good, but it is one approach.<br><br>On Tuesday, March 27, 2012 3:30=
:23 AM UTC-5, Fedor Indutny wrote:<blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;">I think you're just trying to apply existing design habbits to a new =
language.<div><br></div><div>Handling return values works fine for C and ma=
y work fine for Candor too, though it needs to be proved by a practice. The=
 pros of this method is that you always know that code you're calling won't=
 stop execution, which is good for failure-proof applications.</div>

<div><div><div><br clear=3D"all">Cheers,<div>Fedor.</div><br>
<br><br><div class=3D"gmail_quote">On Sat, Mar 24, 2012 at 3:27 AM, Bradley=
 Meck <span dir=3D"ltr">&lt;<a href=3D"mailto:bradley.m...@gmail.com" targe=
t=3D"_blank">bradley.m...@gmail.com</a>&gt;</span> wrote:<br><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;p=
adding-left:1ex">

For now return values are probably enough. In the future, an exception hand=
ler stack might be more appropriate. This may be too intensive because of h=
andling multiple error handler trees (but is quite similar to domains).<div=
>

<div><br></div><div>thisCausesAnException(<wbr>callback) {</div><div>&nbsp;=
 // explicit abort into an exception handler</div><div>&nbsp; callback:abor=
t({reason:'cause I said so'}, {multipleOk: true})</div><div>}</div><div><br=
></div>

<div>doStuff() {</div><div>&nbsp; readAFile(callback() {</div><div>&nbsp; &=
nbsp; thisCausesAnException()</div><div>&nbsp; } catches(e, x) {</div><div>=
&nbsp; &nbsp; print('could not read the file')</div><div>&nbsp; &nbsp; // i=
mplicit throw, up the error handling chain</div>

<div>&nbsp; &nbsp; // akin to a rethrow</div><div>&nbsp; &nbsp; abort(e)</d=
iv><div>&nbsp; })</div><div>} catches(e) {</div><div>&nbsp; print(e.reason)=
;</div><div>}</div><div><br></div><div>Just a brain dump. Though a while ba=
ck I had an idea of 'throwing' into functions, basically avoiding the error=
 first problem of node by allowing functions to have exception handlers tha=
t could be called without ever calling the function (causes uncaught except=
ion handler to fire if the function has no explicit exception handler). Thi=
s would avoid error handler overhead unless functions add them during invoc=
ation when a function can handle errors, as well as have some sanity when j=
ust throwing up the stack.</div>

<div><br></div><div>Cheers,</div><div>Bradley<div><div><br><br>On Friday, M=
arch 23, 2012 2:09:02 PM UTC-5, Tim Caswell wrote:<blockquote class=3D"gmai=
l_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pad=
ding-left:1ex">

Right, this is why I say to never use hard aborts for runtime errors, only =
for invalid configurations.<div><br></div><div>And you're correct, we need =
a story for the more common runtime errors. C does this with return values =
and callback arguments.</div>


<div><br></div><div>The problem with this C style is that it makes it easy =
to ignore errors. &nbsp;If I forget to check the return value of a call the=
n I'll never know it didn't work. &nbsp;Bad stuff will happen down the road=
 and probably segfault or just do nothing.</div>


<div><br></div><div>Perhaps we could add a constraint on the system that re=
turn values can't be ignored. &nbsp;This is hard without static typing and =
static analysis, the parser doesn't know if a function will return a value =
and the runtime is just generated code, we don't want to add in runtime che=
cking and introspection code at every function call. &nbsp;So that idea pro=
bably won't work.</div>


<div><br></div><div>A better convention is maybe an aspect oriented configu=
ration in our libraries where you pass in the error handler to all object c=
reation functions. &nbsp;Then the library can report errors to this. &nbsp;=
Add to this an aspect oriented resource manager and the concept of domains =
and you can register cleanup functions anytime a resource would need to cle=
an if something down the line blew up.</div>


<div><br></div><div>Just spouting off ideas. &nbsp;If in doubt we can just =
take the simple route and require the programmer to check all return values=
 and hope that's good enough.</div><div><br></div><div><br><br><div class=
=3D"gmail_quote">


On Fri, Mar 23, 2012 at 1:49 PM, Bradley Meck <span dir=3D"ltr">&lt;<a href=
=3D"mailto:bradley.m...@gmail.com" target=3D"_blank">bradley.m...@gmail.com=
</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin=
:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">


I would avoid hard abort(). libgmp last time I checked was doing abort() af=
ter encountering errors, which made it prohibitively hard to deal with when=
 you open up fds and cannot close them properly due to aborts. To get aroun=
d this you would need to spawn up a new thread and pass fds around.<div>


<br><br>On Friday, March 23, 2012 12:06:37 PM UTC-5, Tim Caswell wrote:</di=
v><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bor=
der-left:1px #ccc solid;padding-left:1ex"><div>I think hard exceptions (lik=
e failed asserts in C) are fine for things that are obviously programmer er=
ror (like wrong number or types of arguments).&nbsp; in C these are caught =
by the compiler, but we don't have strict type checking in candor. &nbsp;We=
 need some sort of hard assert for this. &nbsp;I could build it into the <a=
 href=3D"http://candor.io" target=3D"_blank">candor.io</a> library and impl=
ement it in C++. It would be nice if I had a way to get the stack trace, or=
 at least the line that threw the assert.<br>




<br>But the other class of errors that you don't want crashing your server =
are invalid user input.&nbsp; The way libuv (The C library behind nodejs an=
d <a href=3D"http://candor.io" target=3D"_blank">candor.io</a>) handles the=
se errors is to return a non-zero status on any function call that potentia=
lly can throw an error.&nbsp; For async functions, there is a status proper=
ty in the callback.&nbsp; It's the responsibility of the programmer to chec=
k for this status code and them pull the actual error message out of libuv =
using the error API.<br>




<br>I've done something like this for <a href=3D"http://candor.io" target=
=3D"_blank">candor.io</a>.&nbsp; It's not pretty, but seems to work ok.&nbs=
p; The only sticky point is sync functions that return a value.&nbsp; Where=
 do I put the status code?&nbsp; In lua this is done with multiple return v=
alues, but I don't think that's a feature we want to add to candor (as much=
 as I love it).<br>




<br><pre style=3D"padding-right:0px;padding-left:0px;border-bottom-width:0p=
x;padding-top:0px;font:inherit;border-style:initial;margin-bottom:0px;borde=
r-color:initial;padding-bottom:0px;border-top-width:0px;line-height:1.4;col=
or:rgb(51,51,51);border-right-width:0px;font-family:'Bitstream Vera Sans Mo=
no','Courier New',monospace;margin-top:0px;border-left-width:0px"><div styl=
e=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padd=
ing-top:0px;padding-right:0px;padding-bottom:0px;padding-left:1em;border-to=
p-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-widt=
h:0px;border-style:initial;border-color:initial;font-size:12px;font:inherit=
">



throw =3D (err) {</div><div style=3D"margin-top:0px;margin-right:0px;margin=
-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-botto=
m:0px;padding-left:1em;border-top-width:0px;border-right-width:0px;border-b=
ottom-width:0px;border-left-width:0px;border-style:initial;border-color:ini=
tial;font-size:12px;font:inherit">



&nbsp;&nbsp;global.prettyPrint(err)</div><div style=3D"margin-top:0px;margi=
n-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right=
:0px;padding-bottom:0px;padding-left:1em;border-top-width:0px;border-right-=
width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initia=
l;border-color:initial;font-size:12px;font:inherit">



&nbsp;&nbsp;global.exit()</div><div style=3D"margin-top:0px;margin-right:0p=
x;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;paddi=
ng-bottom:0px;padding-left:1em;border-top-width:0px;border-right-width:0px;=
border-bottom-width:0px;border-left-width:0px;border-style:initial;border-c=
olor:initial;font-size:12px;font:inherit">



}</div><div style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;marg=
in-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-le=
ft:1em;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;=
border-left-width:0px;border-style:initial;border-color:initial;font-size:1=
2px;font:inherit">



<br></div><div style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;m=
argin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding=
-left:1em;border-top-width:0px;border-right-width:0px;border-bottom-width:0=
px;border-left-width:0px;border-style:initial;border-color:initial;font-siz=
e:12px;font:inherit">



// Used to emit on errors when libuv badness happens</div><div style=3D"mar=
gin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:=
0px;padding-right:0px;padding-bottom:0px;padding-left:1em;border-top-width:=
0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;bo=
rder-style:initial;border-color:initial;font-size:12px;font:inherit">



check =3D (status) {</div><div style=3D"margin-top:0px;margin-right:0px;mar=
gin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bo=
ttom:0px;padding-left:1em;border-top-width:0px;border-right-width:0px;borde=
r-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:=
initial;font-size:12px;font:inherit">



&nbsp;&nbsp;if (status) {</div><div style=3D"margin-top:0px;margin-right:0p=
x;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;paddi=
ng-bottom:0px;padding-left:1em;border-top-width:0px;border-right-width:0px;=
border-bottom-width:0px;border-left-width:0px;border-style:initial;border-c=
olor:initial;font-size:12px;font:inherit">



&nbsp;&nbsp;&nbsp;&nbsp;throw(require('uv').=E2=80=8B=E2=80=8B<wbr>lastErro=
r())</div><div style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;m=
argin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding=
-left:1em;border-top-width:0px;border-right-width:0px;border-bottom-width:0=
px;border-left-width:0px;border-style:initial;border-color:initial;font-siz=
e:12px;font:inherit">



&nbsp;&nbsp;}</div><div style=3D"margin-top:0px;margin-right:0px;margin-bot=
tom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0p=
x;padding-left:1em;border-top-width:0px;border-right-width:0px;border-botto=
m-width:0px;border-left-width:0px;border-style:initial;border-color:initial=
;font-size:12px;font:inherit">



}</div></pre><br></div><pre style=3D"padding-right:0px;padding-left:0px;bor=
der-bottom-width:0px;padding-top:0px;font:inherit;border-style:initial;marg=
in-bottom:0px;border-color:initial;padding-bottom:0px;border-top-width:0px;=
line-height:1.4;color:rgb(51,51,51);border-right-width:0px;font-family:'Bit=
stream Vera Sans Mono','Courier New',monospace;margin-top:0px;border-left-w=
idth:0px"><div><div style=3D"margin-top:0px;margin-right:0px;margin-bottom:=
0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;pa=
dding-left:1em;border-top-width:0px;border-right-width:0px;border-bottom-wi=
dth:0px;border-left-width:0px;border-style:initial;border-color:initial;fon=
t-size:12px;font:inherit">



ServerPrototype =3D {}</div><div style=3D"margin-top:0px;margin-right:0px;m=
argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-=
bottom:0px;padding-left:1em;border-top-width:0px;border-right-width:0px;bor=
der-bottom-width:0px;border-left-width:0px;border-style:initial;border-colo=
r:initial;font-size:12px;font:inherit">



ServerPrototype.listen =3D (self, port, host, callback) {</div><div style=
=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;paddi=
ng-top:0px;padding-right:0px;padding-bottom:0px;padding-left:1em;border-top=
-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width=
:0px;border-style:initial;border-color:initial;font-size:12px;font:inherit"=
>



&nbsp;&nbsp;if (!host) host =3D "0.0.0.0"</div><div style=3D"margin-top:0px=
;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding=
-right:0px;padding-bottom:0px;padding-left:1em;border-top-width:0px;border-=
right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:=
initial;border-color:initial;font-size:12px;font:inherit">



&nbsp;&nbsp;check(self.socket:bind(host, port))</div></div><div style=3D"ma=
rgin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top=
:0px;padding-right:0px;padding-bottom:0px;padding-left:1em;border-top-width=
:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;b=
order-style:initial;border-color:initial;font-size:12px;font:inherit">



&nbsp;&nbsp;check(self.socket:listen(=E2=80=8B=E2=80=8B<wbr>128, (status) {=
</div><div><div style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;=
margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;paddin=
g-left:1em;border-top-width:0px;border-right-width:0px;border-bottom-width:=
0px;border-left-width:0px;border-style:initial;border-color:initial;font-si=
ze:12px;font:inherit">



&nbsp;&nbsp;&nbsp;&nbsp;check(status)</div><div style=3D"margin-top:0px;mar=
gin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-rig=
ht:0px;padding-bottom:0px;padding-left:1em;border-top-width:0px;border-righ=
t-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:init=
ial;border-color:initial;font-size:12px;font:inherit">



&nbsp;&nbsp;&nbsp;&nbsp;client =3D new ClientPrototype</div><div style=3D"m=
argin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-to=
p:0px;padding-right:0px;padding-bottom:0px;padding-left:1em;border-top-widt=
h:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;=
border-style:initial;border-color:initial;font-size:12px;font:inherit">



&nbsp;&nbsp;&nbsp;&nbsp;socket =3D Tcp.create()</div><div style=3D"margin-t=
op:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;p=
adding-right:0px;padding-bottom:0px;padding-left:1em;border-top-width:0px;b=
order-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-=
style:initial;border-color:initial;font-size:12px;font:inherit">



&nbsp;&nbsp;&nbsp;&nbsp;client.socket =3D socket</div><div style=3D"margin-=
top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;=
padding-right:0px;padding-bottom:0px;padding-left:1em;border-top-width:0px;=
border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border=
-style:initial;border-color:initial;font-size:12px;font:inherit">



&nbsp;&nbsp;&nbsp;&nbsp;check(self.socket:accept(=E2=80=8B<wbr>=E2=80=8Bsoc=
ket))</div><div style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;=
margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;paddin=
g-left:1em;border-top-width:0px;border-right-width:0px;border-bottom-width:=
0px;border-left-width:0px;border-style:initial;border-color:initial;font-si=
ze:12px;font:inherit">



&nbsp;&nbsp;&nbsp;&nbsp;self.onConnection(client)</div></div><div style=3D"=
margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-t=
op:0px;padding-right:0px;padding-bottom:0px;padding-left:1em;border-top-wid=
th:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px=
;border-style:initial;border-color:initial;font-size:12px;font:inherit">



&nbsp;&nbsp;&nbsp;&nbsp;check(socket:readStart((=E2=80=8B=E2=80=8B<wbr>nrea=
d, chunk) {</div><div><div><div style=3D"margin-top:0px;margin-right:0px;ma=
rgin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-b=
ottom:0px;padding-left:1em;border-top-width:0px;border-right-width:0px;bord=
er-bottom-width:0px;border-left-width:0px;border-style:initial;border-color=
:initial;font-size:12px;font:inherit">



&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (nread =3D=3D -1) {</div><div style=
=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;paddi=
ng-top:0px;padding-right:0px;padding-bottom:0px;padding-left:1em;border-top=
-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width=
:0px;border-style:initial;border-color:initial;font-size:12px;font:inherit"=
>



&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err =3D require('uv').lastE=
rror()</div><div style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px=
;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;paddi=
ng-left:1em;border-top-width:0px;border-right-width:0px;border-bottom-width=
:0px;border-left-width:0px;border-style:initial;border-color:initial;font-s=
ize:12px;font:inherit">



&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (<a href=3D"http://err.n=
ame" target=3D"_blank">err.name</a> =3D=3D "EOF") {</div><div style=3D"marg=
in-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0=
px;padding-right:0px;padding-bottom:0px;padding-left:1em;border-top-width:0=
px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;bor=
der-style:initial;border-color:initial;font-size:12px;font:inherit">



&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;client.onEnd()<=
/div><div style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margin=
-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left=
:1em;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;bo=
rder-left-width:0px;border-style:initial;border-color:initial;font-size:12p=
x;font:inherit">



&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else {</div><div style=3D=
"margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-=
top:0px;padding-right:0px;padding-bottom:0px;padding-left:1em;border-top-wi=
dth:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0p=
x;border-style:initial;border-color:initial;font-size:12px;font:inherit">



&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw(err)</div=
><div style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margin-lef=
t:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:1em=
;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border=
-left-width:0px;border-style:initial;border-color:initial;font-size:12px;fo=
nt:inherit">



&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div><div style=3D"margin=
-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px=
;padding-right:0px;padding-bottom:0px;padding-left:1em;border-top-width:0px=
;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;borde=
r-style:initial;border-color:initial;font-size:12px;font:inherit">



&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return</div><div style=3D"m=
argin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-to=
p:0px;padding-right:0px;padding-bottom:0px;padding-left:1em;border-top-widt=
h:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;=
border-style:initial;border-color:initial;font-size:12px;font:inherit">



&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div><div style=3D"margin-top:0px;mar=
gin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-rig=
ht:0px;padding-bottom:0px;padding-left:1em;border-top-width:0px;border-righ=
t-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:init=
ial;border-color:initial;font-size:12px;font:inherit">



&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (nread &gt; 0) {</div><div style=3D"=
margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-t=
op:0px;padding-right:0px;padding-bottom:0px;padding-left:1em;border-top-wid=
th:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px=
;border-style:initial;border-color:initial;font-size:12px;font:inherit">



&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;client.onData(chunk)</div><=
div style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:=
0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:1em;b=
order-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-l=
eft-width:0px;border-style:initial;border-color:initial;font-size:12px;font=
:inherit">



&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return</div><div style=3D"m=
argin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-to=
p:0px;padding-right:0px;padding-bottom:0px;padding-left:1em;border-top-widt=
h:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;=
border-style:initial;border-color:initial;font-size:12px;font:inherit">



&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div><div style=3D"margin-top:0px;mar=
gin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-rig=
ht:0px;padding-bottom:0px;padding-left:1em;border-top-width:0px;border-righ=
t-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:init=
ial;border-color:initial;font-size:12px;font:inherit">



&nbsp;&nbsp;&nbsp;&nbsp;}))</div><div style=3D"margin-top:0px;margin-right:=
0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;pad=
ding-bottom:0px;padding-left:1em;border-top-width:0px;border-right-width:0p=
x;border-bottom-width:0px;border-left-width:0px;border-style:initial;border=
-color:initial;font-size:12px;font:inherit">



&nbsp;&nbsp;}))</div><div style=3D"margin-top:0px;margin-right:0px;margin-b=
ottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:=
0px;padding-left:1em;border-top-width:0px;border-right-width:0px;border-bot=
tom-width:0px;border-left-width:0px;border-style:initial;border-color:initi=
al;font-size:12px;font:inherit">



}</div><div><br></div></div></div></pre><div><div><br><div class=3D"gmail_q=
uote">On Fri, Mar 23, 2012 at 11:57 AM, Fedor Indutny <span dir=3D"ltr">&lt=
;<a href=3D"mailto:fe...@indutny.com" target=3D"_blank">fe...@indutny.com</=
a>&gt;</span> wrote:<br>


<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">

<div>Bradley,</div><div><br></div>Exceptions are good, but I'm considering =
Candor to be more like C, than C++.<div><br></div><div>As I know C works fi=
ne w/o exceptions, I'm open to introducing some sort of `abort()` instructi=
on, which will leave candor into C++ land.</div>






<div>Feedback is welcome!</div><div><br clear=3D"all">Cheers,<div>Fedor.</d=
iv><div><div><br>
<br><br><div class=3D"gmail_quote">On Fri, Mar 23, 2012 at 9:29 PM, Bradley=
 Meck <span dir=3D"ltr">&lt;<a href=3D"mailto:bradley.m...@gmail.com" targe=
t=3D"_blank">bradley.m...@gmail.com</a>&gt;</span> wrote:<br><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;p=
adding-left:1ex">






In situations where you are extending a function/method in a way that could=
 cause a need to throw an exception in other languages what is the idea for=
 how to handle this?<div><br></div><div>```candor</div><div>Rect =3D {</div=
>






<div>&nbsp; initialize: (self, w, h) {</div><div>&nbsp; &nbsp; self.w =3D w=
</div><div>&nbsp; &nbsp; self.h =3D h</div><div>&nbsp; }</div><div>}</div><=
div><br></div><div>Square =3D new Rect</div><div>Square.initialize =3D (sel=
f, w, h) {</div><div>&nbsp; &nbsp;if (w !=3D=3D h)</div>






<div>&nbsp; &nbsp; &nbsp; // ?</div><div>&nbsp; &nbsp;Rect.initialize(self,=
 w, h)</div><div>}</div><div>```</div><div><br></div><div>This example is n=
aive, but it will come up in cases where an interface that originally did n=
ot have exceptions / didn't need callbacks to notify exception would sudden=
ly need exceptions. Right now the only way to halt a large nesting of calls=
 seems to have every return checked.</div>






</blockquote></div><br></div></div></div>
</blockquote></div><br>
</div></div></blockquote></blockquote></div><br></div>
</blockquote></div></div></div></div></blockquote></div><br></div></div></d=
iv>
</blockquote>
------=_Part_372_19396901.1332863442458--

------=_Part_371_30169597.1332863442458--