int lua_isstring (lua_State *L, int index);
This function returns 1 if the value at the given acceptable index is
a string or a number (which is always convertible to a string), and 0
otherwise. (Source)
Is there a (more elegant) way to really proof if the given string really is a string and not a number in Lua? This function makes absolutely no sense to me!
My first idea is to additionally examine the string-length with
`if(string.len(String) > 1) {/* this must be a string */}`
... but that does not feel so good.
You can replace
lua_isstring(L, i)
which returns true for either a string or a number by
lua_type(L, i) == LUA_TSTRING
which yields true only for an actual string.
Similarly,
lua_isnumber(L, i)
returns true either for a number or for a string that can be converted to a number; if you want more strict checking, you can replace this with
lua_type(L, i) == LUA_TNUMBER
(I've written wrapper functions, lua_isstring_strict() and lua_isnumber_strict().)
This function makes absolutely no sense to me!
It makes sense in light of Lua's coercion rules. Any function that accepts a string should also accept a number, converting that number to a string. That's just how the language semantics are defined. The way lua_isstring and lua_tostring work allow you automatically implement those semantics in your C bindings with no additional effort.
If you don't like those semantics and want to disable automation conversion between string and number, you can define LUA_NOCVTS2N and/or LUA_NOCVTN2S in your build. In particular, if you define LUA_NOCVTN2S, lua_isstring will return false for numbers.
Related
I'm trying to crate a function in Fortran (95) that that will have as input a string (test) and a character (class). The function will compare each character of test with the character class and return a logical that is .true. if they are of the same class1 and .false. otherwise.
The function (and the program to run it) is defined below:
!====== WRAPPER MODULE ======!
module that_has_function
implicit none
public
contains
!====== THE ACTUAL FUNCTION ======!
function isa(test ,class )
implicit none
logical, allocatable, dimension(:) :: isa
character*(*) :: test
character :: class
integer :: lt
character(len=:), allocatable :: both
integer, allocatable, dimension(:) :: intcls
integer :: i
lt = len_trim(test)
allocate(isa(lt))
allocate(intcls(lt+1))
allocate(character(len=lt+1) :: both)
isa = .false.
both = class//trim(test)
do i = 1,lt+1
select case (both(i:i))
case ('A':'Z'); intcls(i) = 1! uppercase alphabetic
case ('a':'a'); intcls(i) = 2! lowercase alphabetic
case ('0':'9'); intcls(i) = 3! numeral
case default; intcls(i) = 99! checks if they are equal
end select
end do
isa = intcls(1).eq.intcls(2:)
return
end function isa
end module that_has_function
!====== CALLER PROGRAM ======!
program that_uses_module
use that_has_function
implicit none
integer :: i
i = 65
! Reducing the result of "isa" to a scalar with "all" works:
! V-V
do while (all(isa(achar(i),'A')))
print*, achar(i)
i = i + 1
end do
! Without the reduction it doesn''t:
!do while (isa(achar(i),'A'))
! print*, achar(i)
! i = i + 1
!end do
end program that_uses_module
I would like to use this function in do while loops, for example, as it is showed in the code above.
The problem is that, for example, when I use two scalars (rank 0) as input the function still returns the result as an array (rank 1), so to make it work as the condition of a do while loop I have to reduce the result to a scalar with all, for example.
My question is: can I make the function conditionally return a scalar? If not, then is it possible to make the function work with vector and scalar inputs and return, respectively, vector and scalar outputs?
1. What I call class here is, for example, uppercase or lowercase letters, or numbers, etc. ↩
You can not make the function conditionally return a scalar or a vector.
But you guessed right, there is a solution. You will use a generic function.
You write 2 functions, one that takes scalar and return scalar isas, the 2nd one takes vector and return vector isav.
From outside of the module you will be able to call them with the same name: isa. You only need to write its interface at the beginning of the module:
module that_has_function
implicit none
public
interface isa
module procedure isas, isav
end interface isa
contains
...
When isa is called, the compiler will know which one to use thanks to the type of the arguments.
The rank of a function result cannot be conditional on the flow of execution. This includes selection by evaluating an expression.
If reduction of a scalar result is too much, then you'll probably be horrified to see what can be done instead. I think, for instance, of derived types and defined operations.
However, I'd consider it bad design in general for the function reference to be unclear in its rank. My answer, then, is: no you can't, but that's fine because you don't really want to.
Regarding the example of minval, a few things.1 As noted in the comment, minval may take a dim argument. So
integer :: X(5,4) = ...
print *, MINVAL(X) ! Result a scalar
print *, MINVAL(X,dim=1) ! Result a rank-1 array
is in keeping with the desire of the question.
However, the rank of the function result is still "known" at the time of referencing the function. Simply having a dim argument means that the result is an array of rank one less than the input array rather than a scalar. The rank of the result doesn't depend on the value of the dim argument.
As noted in the other answer, you can have similar functionality with a generic interface. Again, the resolved specific function (whichever is chosen) will have a result of known rank at the time of reference.
1 The comment was actually about minloc but minval seems more fitting to the topic.
If I want to check if a string starts with a letter and the rest of the characters can either be a letter or number, how would I define a datatype that is defined by those conditions? Or would pattern matching be the better route and if so, how would I check that?
If you don't care that using String.explode is a bit inefficient, then you can just define this predicate:
fun isName s = List.all Char.isAlpha (String.explode s)
Otherwise, you'd implement it via recursion over (the length of) the string itself.
I' m having a problem parsing the lat and long cords from TinyGPS++ to a Double or a string. The code that i'm using is:
String latt = ((gps.location.lat(),6));
String lngg = ((gps.location.lng(),6));
Serial.println(latt);
Serial.println(lngg);
The output that i'm getting is:
0.06
Does somebody know what i'm doing wrong? Does it have something to do with rounding? (Math.Round) function in Arduino.
Thanks!
There are two problems:
1. This does not compile:
String latt = ((gps.location.lat(),6));
The error I get is
Wouter.ino:4: warning: left-hand operand of comma has no effect
Wouter:4: error: invalid conversion from 'int' to 'const char*'
Wouter:4: error: initializing argument 1 of 'String::String(const char*)'
There is nothing in the definition of the String class that would allow this statement. I was unable to reproduce printing values of 0.06 (in your question) or 0.006 (in a later comment). Please edit your post to have the exact code that compiles, runs and prints those values.
2. You are unintentionally using the comma operator.
There are two places a comma can be used: to separate arguments to a function call, and to separate multiple expressions which evaluate to the last expression.
You're not calling a function here, so it is the latter use. What does that mean? Here's an example:
int x = (1+y, 2*y, 3+(int)sin(y), 4);
The variable x will be assigned the value of the last expression, 4. There are very few reasons that anyone would actually use the comma operator in this way. It is much more understandable to write:
int x;
1+y; // Just a calculation, result never used
2*y; // Just a calculation, result never used
3 + (int) sin(y); // Just a calculation, result never used
x = 4; // A (trivial) calculation, result stored in 'x'
The compiler will usually optimize out the first 3 statements and only generate code for the last one1. I usually see the comma operator in #define macros that are trying to avoid multiple statements.
For your code, the compiler sees this
((gps.location.lat(),6))
And evaluates it as a call to gps.location.lat(), which returns a double value. The compiler throws this value away, and even warns you that it "has no effect."
Next, it sees a 6, which is the actual value of this expression. The parentheses get popped, leaving the 6 value to be assigned to the left-hand side of the statement, String latt =.
If you look at the declaration of String, it does not define how to take an int like 6 and either construct a new String, or assign it 6. The compiler sees that String can be constructed from const char *, so it tells you that it can't convert a numeric 6 to a const char *.
Unlike a compiler, I think I can understand what you intended:
double latt = gps.location.lat();
double lngg = gps.location.lon();
Serial.println( latt, 6 );
Serial.println( lngg, 6 );
The 6 is intended as an argument to Serial.println. And those arguments are correctly separated by a comma.
As a further bonus, it does not use the String class, which will undoubtedly cause headaches later. Really, don't use String. Instead, hold on to numeric values, like ints and floats, and convert them to text at the last possible moment (e.g, with println).
I have often wished for a compiler that would do what I mean, not what I say. :D
1 Depending on y's type, evaluating the expression 2*y may have side effects that cannot be optimized away. The streaming operator << is a good example of a mathematical operator (left shift) with side effects that cannot be optimized away.
And in your code, calling gps.location.lat() may have modified something internal to the gps or location classes, so the compiler may not have optimized the function call away.
In all cases, the result of the call is not assigned because only the last expression value (the 6) is used for assignment.
In AS3, do two Strings with the same value always have the same exact reference, without exception? In particular, I'm wondering if things like concatenated strings and strings returned from a web service can create duplicate instances of the same exact value.
For instance:
class Example
{
const MY_STRING:String = "Example";
.
.
.
private function myWebMethodResultHandler(pResult:ResultEvent):void
{
var myWebMethodString:String = pResult.result as String;
trace(myWebMethodString === MY_STRING); // returns true;
}
.
.
.
private function someOtherFunction():void
{
var str1:String = "Ex";
var str2:String = "ample";
var concatenatedString:String = str1 + str2;
trace(concatenatedString === MY_STRING); // returns true;
}
}
Is it absolutely guaranteed that in every case, including the ones above, that two Strings in AS3 with the same value are also the same exact instance with the same exact reference, or are there any cases at all in which Strings could be stored separately and as duplicate instances, taking up twice as much memory (and causing String comparisons to be more complicated internally than just comparing two 32-bit references)?
That is not correct, primitive types in AS3 are not compared by reference in strict equality but by value. The strict equality by reference is reserved to complex objects. 2 string with same value will never have the same reference (this is not Python).
Now AS3 is not the only language that treats primitive differently when it comes to strict comparison and because strict equality means same reference for complex object it is normal to assume the same is true for primitives but it's not. And yes constructing the same string 5 times will result in 5 different reference and 5 different object built but this is handled efficiently in AS3 like in other languages. As mentioned a language like Python does cache primitives and in that case 2 equal string or number are likely to point to the same reference but Python in that domain is more the exception than the rule.
So to resume a bit, strict equality in AS3 can be used to check strict equality between complex objects but when it comes to primitives it has no special meaning since it only compares values which is the same as simple equality.
Why does
if (x) {
f();
}
call f() if x is an empty string ""?
Shouldn't empty strings in D implicitly convert to bool false like they do in Python and when empty arrays does it (in D)?
Update: I fixed the question. I had incorrectly reversed the reasoning logic. Luckily, the bright D minds understood what I meant anyway ;)
Conditions and if statements and loops are cast to bool by the compiler. So,
if(x) {...}
becomes
if(cast(bool)x) {...}
and in the case of arrays, casting to bool is equivalent to testing whether its ptr property is not null. So, it becomes
if(x.ptr !is null) {...}
In the case of arrays, this is actually a really bad test, because null arrays are considered to be the same as empty arrays. So, in most cases, you don't care whether an array is null or not. An array is essentially a struct that looks like
struct Array(T)
{
T* ptr;
size_t length;
}
The == operator will check whether all of the elements referred to by ptr are equal, but if length is 0 for both arrays, it doesn't care what the value of ptr is. That means that "" and null are equal (as are [] and null). However, the is operator explicitly checks the ptr properties for equality, so "" and null won't be the same according to the is operator, and whether a particular array which is empty has a null ptr depends on how its value was set. So, the fact that an array is empty really says nothing about whether it's null or not. You have to check with the is operator to know for sure.
The result of all this is that it's generally bad practice to put an array (or string) directly in a condition like you're doing with
if(x) {...}
Rather, you should be clear about what you're checking. Do you care whether it's empty? In that case, you should check either
if(x.empty) {...}
or
if(x.length == 0} {...}
Or do you really care that it's null? In that case, use the is operator:
if(x is null) {...}
The behavior of arrays in conditions is consistent with the rest of the language (e.g. pointer and reference types are checked to see whether they're null or not), but unfortunately, in practice, such behavior for arrays is quite bug-prone. So, I'd advise that you just don't ever put an array by itself in the condition of an if statement or loop.
the default conversion of arrays looks at the .ptr, which means only the default initialized arrays (or explicitly set to null) evaluate to false
as an added effect string literals in D are \0 terminated which means ("")[0] == '\0' and as such ("").ptr can't be null (which would lead to a segfault)
IMO it should look at the length and you can use the ptr when you need to
It does when I try it...
void main() {
import std.stdio;
string s = "";
if(s)
writeln("true"); // triggered
}
If it was "string s = null;" (which is the default initialization), it doesn't, because the null converts to false, but "" is ok on my computer. Are you sure it isn't null?
BTW, if you want to test for (non-)emptiness, the way I prefer to do it is if(x.length) and if(x.length == 0). Those work consistently for both "" and null, then if you specifically want null, do if(x is null). It is just a little more clear, especially since "" and null are interchangeable in a lot of other contexts in D.