user59254: Many arduino functions return -1 if something 'fails'. Serial.read for example returns -1 or the infamous ÿ when this function is called while the serial buffer is empty.
As embedded C progammer, I am personally a fan of letting functions return data in the form of modifying pointers which points to passed on addresses and return states with the actual return functionality of a function. I am used to return a 0 if a function is 'not done' or 'failed'. 
I see no logic in why many arduino functions return an int type which contains -1 instead of just a 0. 
Would it not be better to let functions return a boolean type or an unsigned char type in which false or '0' would indicate a 'failed' process and true or '1' would indicate a 'succesful' process?
Also: if I type: 
if(Serial.read()) {/* body */ }
and Serial.read() returns -1 because the buffer is empty. Will the If's body be executed or not?

user37622: Arduino API is port of Processing. Processing is Java API to communicate with a MCU running Firmata. Arduino enabled sketches with the same API to run directly on the MCU.
So for example stream functions from Java stream classes were ported to Arduino API. This includes the read() function, to read one byte. Of course Java and Java basic libraries have inspiration in C++. 
For other read and write functions, if the return value is count of bytes written or read then 0 is a valid return value and -1 indicates error.
Processing, Wiring and Arduino were created by interactive arts teachers and students, not by embedded systems developers. So you can't wonder about not ideal data types used. Later some things were improved by software developers.

as embedded C developer you should know that:

0 is a valid value to read, so it can't be a value indicating error
'if' executes if the evaluated value is not 0


user7508: I cannot assert anything for sure, as I was not involved in the design
of the Arduino APIs. However, just like Elliot Alderson, I suspect this
was inspired by the traditional C APIs. The manual page for getchar(),
which is a very old function from the standard C library, states:

fgetc(),  getc() and getchar() return the character read
  as an unsigned char cast to an int or EOF on end of file or
  error.

Given that EOF is usually defined as -1, this is consistent with the
behavior of Serial.read().
Being beginner-friendly is also a major goal of the API. Pointers are
known to be a huge difficulty for beginners.
There may also be some efficiency considerations involved. Arduino
started on the AVR platform. This is a RISC architecture, with a large
number of generic CPU registers (namely 32). The compiler usually
manages to allocate most local variables to registers. The calling
convention ensures that in most cases function parameters and return
values also go through CPU registers. This means we can avoid many RAM
accesses, which are inherently much slower than register access. Using a
return-by-pointer convention defeats these optimizations.
Lastly, it is a good thing that simple things are easy to write. For
example, an interpreter for single-character commands can be very easily
written as:
switch (Serial.read()) {
case 'a':
    do_command_a();
    break;
case 'b':
    do_command_b();
    break;
// etc...
}

with no need to explicitly test for the serial buffer not being empty.
Obviously, a more complex command language will need a full-blown
interpreter, but the focus of Arduino has always been on simple
programs being easy to write.

59254: <p>Many arduino functions return -1 if something 'fails'. Serial.read for example returns -1 or the infamous ÿ when this function is called while the serial buffer is empty.</p>

<p>As embedded C progammer, I am personally a fan of letting functions return data in the form of modifying pointers which points to passed on addresses and return states with the actual return functionality of a function. I am used to return a 0 if a function is 'not done' or 'failed'. </p>

<p>I see no logic in why many arduino functions return an int type which contains -1 instead of just a 0. </p>

<p>Would it not be better to let functions return a boolean type or an unsigned char type in which false or '0' would indicate a 'failed' process and true or '1' would indicate a 'succesful' process?</p>

<p>Also: if I type: 
<code>if(Serial.read()) {/* body */ }</code>
and <code>Serial.read()</code> returns -1 because the buffer is empty. Will the If's body be executed or not?</p>
 37622: <p>Arduino API is port of Processing. Processing is Java API to communicate with a MCU running Firmata. Arduino enabled sketches with the same API to run directly on the MCU.</p>

<p>So for example stream functions from Java stream classes were ported to Arduino API. This includes the <a href="https://docs.oracle.com/javase/8/docs/api/java/io/InputStream.html#read--" rel="nofollow noreferrer">read() function</a>, to read one byte. Of course Java and Java basic libraries have inspiration in C++. </p>

<p>For other read and write functions, if the return value is count of bytes written or read then 0 is a valid return value and -1 indicates error.</p>

<p>Processing, Wiring and Arduino were created by interactive arts teachers and students, not by embedded systems developers. So you can't wonder about not ideal data types used. Later some things were improved by software developers.</p>

<hr>

<p>as embedded C developer you should know that:</p>

<ul>
<li>0 is a valid value to read, so it can't be a value indicating error</li>
<li>'if' executes if the evaluated value is not 0</li>
</ul>
 7508: <p>I cannot assert anything for sure, as I was not involved in the design
of the Arduino APIs. However, just like Elliot Alderson, I suspect this
was inspired by the traditional C APIs. The manual page for <code>getchar()</code>,
which is a very old function from the standard C library, states:</p>

<blockquote>
  <p><strong>fgetc</strong>(),  <strong>getc</strong>() and <strong>getchar</strong>() return the character read
  as an <em>unsigned char</em> cast to an <em>int</em> or <strong>EOF</strong> on end of file or
  error.</p>
</blockquote>

<p>Given that <code>EOF</code> is usually defined as <code>-1</code>, this is consistent with the
behavior of <code>Serial.read()</code>.</p>

<p>Being beginner-friendly is also a <em>major</em> goal of the API. Pointers are
known to be a <em>huge</em> difficulty for beginners.</p>

<p>There may also be some efficiency considerations involved. Arduino
started on the AVR platform. This is a RISC architecture, with a large
number of generic CPU registers (namely 32). The compiler usually
manages to allocate most local variables to registers. The calling
convention ensures that in most cases function parameters and return
values also go through CPU registers. This means we can avoid many RAM
accesses, which are inherently much slower than register access. Using a
return-by-pointer convention defeats these optimizations.</p>

<p>Lastly, it is a good thing that simple things are easy to write. For
example, an interpreter for single-character commands can be very easily
written as:</p>

<pre class="lang-cpp prettyprint-override"><code>switch (Serial.read()) {
case 'a':
    do_command_a();
    break;
case 'b':
    do_command_b();
    break;
// etc...
}
</code></pre>

<p>with no need to explicitly test for the serial buffer not being empty.
Obviously, a more complex command language will need a full-blown
interpreter, but the focus of Arduino has always been on <em>simple</em>
programs being easy to write.</p>
