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"><<a href=3D"mailto:bradley.m...@gmail.com" targe=
t=3D"_blank">bradley.m...@gmail.com</a>></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> =
// explicit abort into an exception handler</div><div> callback:abor=
t({reason:'cause I said so'}, {multipleOk: true})</div><div>}</div><div><br=
></div>
<div>doStuff() {</div><div> readAFile(callback() {</div><div> &=
nbsp; thisCausesAnException()</div><div> } catches(e, x) {</div><div>=
print('could not read the file')</div><div> // i=
mplicit throw, up the error handling chain</div>
<div> // akin to a rethrow</div><div> abort(e)</d=
iv><div> })</div><div>} catches(e) {</div><div> 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. If I forget to check the return value of a call the=
n I'll never know it didn't work. 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. 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. 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. Then the library can report errors to this. =
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. 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"><<a href=
=3D"mailto:bradley.m...@gmail.com" target=3D"_blank">bradley.m...@gmail.com=
</a>></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). in C these are caught =
by the compiler, but we don't have strict type checking in candor. We=
need some sort of hard assert for this. 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. 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. For async functions, there is a status proper=
ty in the callback. 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>. It's not pretty, but seems to work ok.&nbs=
p; The only sticky point is sync functions that return a value. Where=
do I put the status code? 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">
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">
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">
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">
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">
}</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"=
>
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">
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">
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">
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">
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">
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">
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">
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">
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">
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">
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"=
>
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">
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">
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">
} 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">
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">
}</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">
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">
}</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">
if (nread > 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">
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">
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">
}</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">
}))</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">
}))</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"><=
;<a href=3D"mailto:fe...@indutny.com" target=3D"_blank">fe...@indutny.com</=
a>></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"><<a href=3D"mailto:bradley.m...@gmail.com" targe=
t=3D"_blank">bradley.m...@gmail.com</a>></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> initialize: (self, w, h) {</div><div> self.w =3D w=
</div><div> self.h =3D h</div><div> }</div><div>}</div><=
div><br></div><div>Square =3D new Rect</div><div>Square.initialize =3D (sel=
f, w, h) {</div><div> if (w !=3D=3D h)</div>
<div> // ?</div><div> 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--