I'm a newbie in ML languages. I'm reading the ATS manual and I in mad now.
I read half of manual and there is no explanation in it how to compile a non-void function.
Only one example with "hello world" program.
ats
val x = "hello"
implement main0 () = print x
But if I change x to 2 * 2 it will raise an error.
Should I read the manual without capability to compile code and test it? Disgusting.
You need the following line for
some library functions:
#include "share/atspre_staload.hats"
ATS may not be a good language for beginners as it assumes
a fair amount of knowledge of ML and C.
Related
I study Computer Science in college and one of my group tasks is to create a simple statement lexical analyzer, along with a simple arithmetic expression, simple conditional If with block, and simple looping with conditional If block. I'm trying my hand at making at least a simple statement lexical analyzer.
However, I have no clue on how to code with Pascal language as I was never taught this language over the course of my 5 semesters in college.
I tried looking up documentations of Pascal programming language along with various examples of it online while trying to do it myself on an online compiler, cross referencing a lexical analyzer made with C language and tried converting it myself into Pascal language.
It turned out to be more complicated than I had anticipated.
Again, I am very new to Pascal language, just starting a few days ago in fact. So if there are any tips or examples, preferably short and to the point, it would be very much appreciated, thanks.
If you want to see my code, its not much, as I was more focused on grasping the language. The only languages I was taught and can understand is Java and C, along with a little bit of PHP.
program SimpleStatement;
var letters: array['a'...'z'] of char,
numbers: array['1'...'9'] of integer,
symbols: char;
function letVer(letters : char): boolean;
begin
clrscr;
if(letters = 'a'...'z') then
begin
for letters: 'a' to 'z' do
writeln('keywords: ', letters)
end
letVer = true;
end
begin
letVer;
writeln ();
end.
Along with the error code:
Free Pascal Compiler version 3.0.4+dfsg-23 [2019/11/25] for x86_64
Copyright (c) 1993-2017 by Florian Klaempfl and others
Target OS: Linux for x86-64
Compiling main.pas
main.pas(12,23) Error: Error in type definition
main.pas(12,23) Fatal: Syntax error, "]" expected but "..." found
Fatal: Compilation aborted
Error: /usr/bin/ppcx64 returned an error exitcode
A snip of Rust code:
pub fn main() {
let a = "hello";
let b = a.len();
let c =b;
println!("len:{}",c)
}
When debugging in CLion, Is it possible to evaluate a function? For example, debug the code step by step, now the code is running to the last line println!... and the current step stops here, by adding the expression a.len() to the watch a variable window, the IDE can't evaluate the a.len(). It says: error: no field named len
This is the same reason you can't make conditional breakpoints for Rust code:
Can't create a conditional breakpoint in VSCode-LLDB with Rust
I hope, I'm not too late to answer this, but with both lldb and gdb, Rust debugging capability is currently rather constrained.
Expressions that are straightforward work; anything complex is likely to produce issues.
My observations from rust-lldb trying this, are that only a small portion of Rust is understood by the expression parser.
There is no support for macros.
Non-used functions are not included in the final binary.
For instance, since that method is not included in the binary, you are unable to execute capacity() on the HashMap in the debugger.
Methods must be named as follows:
struct value.method(&struct value)
There is no technique that I've discovered to call monomorphized functions on generic structs (like HashMap).
For example, "hello" is a const char [5] including the trailing NUL byte. String constants "..." in lldb expressions are produced as C-style string constants.
Therefore, they are not valid functions
I'm reading Bjarne Stroustrup's book, "The C++ Programming Language" and I found an example explaining static_assert. What I understood is that static_assert only works with things that can be expressed by constant expressions. In other words, it must not include an expression that's meant to be evaluated at runtime.
The following example was used in the book (I did some changes in the code. But I don't think that should change anything that'd be produced by the original example code given in the book.)
#include <iostream>
using namespace std;
void f (double speed)
{
constexpr double C = 299792.468;
const double local_max = 160.0/(60*60);
static_assert(local_max<C,"can't go that fast");
}
int main()
{
f(3.25);
cout << "Reached here!";
return 0;
}
The above gives a compile error. Here's it compiled using ideone: http://ideone.com/C97oF5
The exact code from the book example:
constexpr double C = 299792.458;
void f(double speed)
{
const double local_max = 160.0/(60∗60);
static_assert(speed<C,"can't go that fast"); // yes this is error
static_assert(local_max<C,"can't go that fast");
}
The compiler does not know the value of speed at compile time. It makes sense that it cannot evaluate speed < C at compile time. Hence, a compile time error is expected when processing the line
static_assert(speed<C,"can't go that fast");
The language does not guarantee that floating point expressions be evaluated at compile time. Some compilers might support it but that's not to be relied upon.
Even though the values of the floating point variables are "constants" to a human reader, they are not necessarily evaluated at compile time. The error message from the compiler from the link you provided makes it clear.
static_assert expression is not an integral constant expression
You'll have to find a way to do the comparison using integral expressions. However, that seems to be a moot point. I suspect, what you really want to do is make sure that speed is within a certain limit. That makes sense only as a run time check.
I've profiled my program with Valgrind and Callgrind and found that most of the time is spent in the nearbyint$fenv_access_off function.
I've found that it's a LLVM intrinsic, but which Rust language construct uses it? How can I avoid it?
Doing a search for nearbyint finds the related symbols nearbyintf32 and nearbyintf64. These are documented as returning the nearest integer to a floating point value. However, there appears to be no calls to that specific function.
fenv_access_off appears to be an OS X specific aspect of the math library.
The other thing in your trace is round. I can believe that round could use nearbyint. I also don't see any cases of round in the standard library that seem like they would occur in a tight loop.
Beyond this, anything is pure guessing.
I've reproduced it with:
fn main() {
let data:Vec<_> = (0..999999).map(|x|{
(x as f64).powf(2.2).round() as u8
}).collect();
}
so it seems as u8 is implemented using nearbyint.
It's the same speed as C uchar = round(pow(i, 2.2)), so I'll have to replace it with a good'ol lookup table…
I am concerned about writing self-modifying code in Ruby. And by self-modifying, I mean being able to write functions that take a code block as an input value, and output another code block based on this. (I am not asking about basics such as redefining methods at runtime.)
What I might want to do is, for example, having the following block,
_x_ = lambda { |a, b, c, d| b + c }
one can notice that arguments a and d are not used in the body at all, so I would like a function eg. #strip to remove them,
x = _x_.strip
which should produce same result as writing:
x = lambda { |b, c| b + c }
Now in Lisp, this would be easy, since Lisp code is easily manipulable data. But I do not know how to manipulate Ruby code. I can parse it eg. by
RubyVM::InstructionSequence.disassemble( x )
But how, based on this, do I write a modified block? Other examples of what I would want to do are are eg.
y = lambda { A + B }
y.deconstantize
# should give block same as saying
lambda { |_A, _B| _A + _B }
So far, in Ruby, I have never encountered a situation where I had to concede that something is not possible. But this time, gut feeling tells me that I might have encountered the fundamental weakness of beautifully structured code vs. code with little syntax to speak about (which would be Lisp). Please enlighten me.
Detecting whether a block variable is used or not is a complicated task, and you seem to be saying that you can do that by using RubyVM. So the question seems to be asking how to change the arity of the code.
If you have:
_x_ = ->a, b, c, d{b + c}
and suppose you were able to use RubyVM and come to know that a and d are not used, so you want to create
x = ->b, c{b + c}
out of _x_. Then, that is simple:
x = ->b, c{_x_.call(nil, b, c, nil)}
Boris do you necessarily have to rely on Ruby to begin with here?
Why not just create your own situation-specific language that the chemists can use just for the purpose to express their formulas in the most convenient way. Then you create a simple parser and compiler for this "chemical expression language".
What I mean is this parser and compiler will parse and compile the expressions the chemists write in their Ruby code. Then you could have:
ChemicalReaction.new(..., "[ATP] * [GDP] * NDPK_constant")
Voila: ultimate flexibility.
That's the approach I would take if usability is your main concern. Already writing out "lambda" seems like an unnecessarily cumbersome thing to me here, if all you want to do is express some domain-specific formula in the most compact way possible.