In a visit expression, can the default be labeled like the cases? - rascal

Example:
visit(Sometree)
{
case a:someNodeA(_,_): HandleNodeA(a);
default: Handle(???);
}
So i want to handle all the other cases by using default, how can I do this?

visit does not support default because it needs something specific to bind while visiting. Instead you can write a pattern that matches truly everything. For example:
visit(sometree) {
case node x : handleAllTreeLikeThings(x);
case str y(value x, value y) : handleAllBinaryTrees(y, x, y);
case value x : handleAllValuesWhatsoever(x);
}

Related

Why does Dart typing system make equate difficult and does that bar pattern matching?

I tried to do this thing in dart but it failed and I don't really understand why. I know that dart doesn't support robust "Pattern Matching" like elixir does, but I thought it should be able to compare two lists. No. Why not? what is it about the typing system that can't equate two lists and if it could, could it support even rudimentary pattern matching? I'm just trying to understand how equate works in dart I guess.
void main() {
final x = 1;
final y = 2;
if (x == 1 && y == 2) {
print('this works fine of course');
}
if ([1, 2] == [1, 2]) {
print('but this does not');
}
if ([x, y] == [1, 2]) {
print('would this work if dart could equate lists?');
}
}
Dart lists do not implement operator== in a way that checks the elements for equality.
Dart lists are assumed to be mutable, and the Dart platform libraries generally do not provide an equality for mutable objects, because they are not guaranteed to preserve that equality over time.
Also, for lists, because it's not obvious which equality to use. Should it just compare elements? Then a <num>[1] list would be equal to <int>[1], even if they are very different lists.
For those reasons, you are supposed to decide which equality you actually want, without one being the canonical one.
You can, for example, use const ListEquality().equals from package:collection. It defaults to using == on the elements, but can be configured to use other equalities as well.
import 'package:flutter/foundation.dart';
void main() async {
final x = 1;
final y = 2;
if (x == 1 && y == 2) {
print('this works fine of course');
}
if (listEquals([1, 2],[1, 2])) {
print('Yep');
}
if (listEquals([x, y], [1, 2])) {
print('would this work if dart could equate lists? Yep');
}
}
Output:
this works fine of course
Yep
would this work if dart could equate lists? Yep

How to calculate this String text ="2+3-5+1" using Split method? [duplicate]

This question already has answers here:
Calculate string value in javascript, not using eval
(12 answers)
Closed 4 months ago.
When the text was '2+3+5+1', the logic was easy
Split('+') so the string is converted to an array.
loop over the array and calculate the sum.
check the code below
void main() {
const text = '2+3+5+1';
final array = text.split('+');
int res =0;
for (var i=0; i<= array.length -1; i++){
res+=int.parse(array[i]);;
}
print(array);
print(res);
}
Now this String "2+3-5+1" contains minus.
how to get the right response using split method?
I am using dart.
note: I don't want to use any library (math expression) to solve this exercice.
Use the .replace() method.
text = text.replace("-", "+-");
When you run through the loop, it will calculate (-).
You can split your string using regex text.split(/\+|\-/).
This of course will fail if any space is added to the string (not to mention *, / or even decimal values).
const text = '20+3-5+10';
const arr = text.split(/\+|\-/)
let tot = 0
for (const num of arr) {
const pos = text.indexOf(num)
if (pos === 0) {
tot = parseInt(num)
} else {
switch (text.substr(text.indexOf(num) - 1, 1)) {
case '+':
tot += parseInt(num)
break
case '-':
tot -= parseInt(num)
break
}
}
}
console.log(tot)
I see 2 maybe 3 options, definitely there are hundreds
You don't use split and you just iterate through the string and just add or subtract on the way. As an example
You have '2+3-5+1'. You iterate until the second operator (+ or -) on your case. When you find it you just do the operation that you have iterated through and then you just keep going. You can do it recursive or not, doesn't matter
"2+3-5+1" -> "5-5+1" -> "0+1" -> 1
You use split on + for instance and you get [ '2', '3-5', '1' ] then you go through them with a loop with 2 conditions like
if(isNaN(x)) res+= x since you know it's been divided with a +
if(!isNaN(x)) res+= x.split('-')[0] - x.split('-')[1]
isNaN -> is not a number
Ofc you can make it look nicer. If you have parenthesis though, none of this will work
You can also use regex like split(/[-+]/) or more complex, but you'll have to find a way to know what operation follows each digit. One easy approach would be to iterate through both arrays. One of numbers and one of operators
"2+3-5+1".split(/[-+]/) -> [ '2', '3', '5', '1' ]
"2+3-5+1".split(/[0-9]*/).filter(x => x) -> [ '+', '-', '+' ]
You could probably find better regex, but you get the idea
You can ofc use a map or a switch for multiple operators

Destructured iteration over variadic arguments like a tuple sequence in D

Let's say I want to process a variadic function which alternately gets passed start and end values of 1 or more intervals and it should return a range of random values in those intervals. You can imagine the input to be a flattened sequence of tuples, all tuple elements spread over one single range.
import std.meta; //variadic template predicates
import std.traits : isFloatingPoint;
import std.range;
auto randomIntervals(T = U[0], U...)(U intervals)
if (U.length/2 > 0 && isFloatingPoint!T && NoDuplicates!U.length == 1) {
import std.random : uniform01;
T[U.length/2] randomValues;
// split and iterate over subranges of size 2
foreach(i, T start, T end; intervals.chunks(2)) { //= intervals.slide(2,2)
randomValues[i] = uniform01 * (end - start) + start,
}
return randomValues.dup;
}
The example is not important, I only use it for explanation. The chunk size could be any finite positive size_t, not only 2 and changing the chunk size should only require changing the number of loop-variables in the foreach loop.
In this form above it will not compile since it would only expect one argument (a range) to the foreach loop. What I would like is something which rather automatically uses or infers a sliding-window as a tuple, derived from the number of given loop-variables, and fills the additional variables with next elements of the range/array + allows for an additional index, optionally. According to the documentation a range of tuples allows destructuring of the tuple elements in place into foreach-loop-variables so the first thing, I thought about, is turning a range into a sequence of tuples but didn't find a convenience function for this.
Is there a simple way to loop over destructured subranges (with such a simplicity as shown in my example code) together with the index? Or is there a (standard library) function which does this job of splitting a range into enumerated tuples of equal size? How to easily turn the range of subranges into a range of tuples?
Is it possible with std.algorithm.iteration.map in this case (EDIT: with a simple function argument to map and without accessing tuple elements)?
EDIT: I want to ignore the last chunk which doesn't fit into the entire tuple. It just is not iterated over.
EDIT: It's not, that I couldn't program this myself, I only hope for a simple notation because this use case of looping over multiple elements is quite useful. If there is something like a "spread" or "rest" operator in D like in JavaScript, please let me know!
Thank you.
(Added as a separate answer because it's significantly different from my previous answer, and wouldn't fit in a comment)
After reading your comments and the discussion on the answers thus far, it seems to me what you seek is something like the below staticChunks function:
unittest {
import std.range : enumerate;
size_t index = 0;
foreach (i, a, b, c; [1,2,3,1,2,3].staticChunks!3.enumerate) {
assert(a == 1);
assert(b == 2);
assert(c == 3);
assert(i == index);
++index;
}
}
import std.range : isInputRange;
auto staticChunks(size_t n, R)(R r) if (isInputRange!R) {
import std.range : chunks;
import std.algorithm : map, filter;
return r.chunks(n).filter!(a => a.length == n).map!(a => a.tuplify!n);
}
auto tuplify(size_t n, R)(R r) if (isInputRange!R) {
import std.meta : Repeat;
import std.range : ElementType;
import std.typecons : Tuple;
import std.array : front, popFront, empty;
Tuple!(Repeat!(n, ElementType!R)) result;
static foreach (i; 0..n) {
result[i] = r.front;
r.popFront();
}
assert(r.empty);
return result;
}
Note that this also deals with the last chunk being a different size, if only by silently throwing it away. If this behavior is undesirable, remove the filter, and deal with it inside tuplify (or don't, and watch the exceptions roll in).
chunks and slide return Ranges, not tuples. Their last element can contain less than the specified size, whereas tuples have a fixed compile time size.
If you need destructuring, you have to implement your own chunks/slide that return tuples. To explicitly add an index to the tuple, use enumerate. Here is an example:
import std.typecons, std.stdio, std.range;
Tuple!(int, int)[] pairs(){
return [
tuple(1, 3),
tuple(2, 4),
tuple(3, 5)
];
}
void main(){
foreach(size_t i, int start, int end; pairs.enumerate){
writeln(i, ' ', start, ' ', end);
}
}
Edit:
As BioTronic said using map is also possible:
foreach(i, start, end; intervals
.chunks(2)
.map!(a => tuple(a[0], a[1]))
.enumerate){
Your question has me a little confused, so I'm sorry if I've misunderstood. What you're basically asking is if foreach(a, b; [1,2,3,4].chunks(2)) could work, right?
The simple solution here is to, as you say, map from chunk to tuple:
import std.typecons : tuple;
import std.algorithm : map;
import std.range : chunks;
import std.stdio : writeln;
unittest {
pragma(msg, typeof([1,2].chunks(2).front));
foreach(a, b; [1,2,3,4].chunks(2).map!(a => tuple(a[0], a[1]))) {
writeln(a, ", ", b);
}
}
At the same time with BioTronic, I tried to code some own solution to this problem (tested on DMD). My solution works for slices (BUT NOT fixed-size arrays) and avoids a call to filter:
import std.range : chunks, isInputRange, enumerate;
import std.range : isRandomAccessRange; //changed from "hasSlicing" to "isRandomAccessRange" thanks to BioTronics
import std.traits : isIterable;
/** turns chunks into tuples */
template byTuples(size_t N, M)
if (isRandomAccessRange!M) { //EDITED
import std.meta : Repeat;
import std.typecons : Tuple;
import std.traits : ForeachType;
alias VariableGroup = Tuple!(Repeat!(N, ForeachType!M)); //Tuple of N repititions of M's Foreach-iterated Type
/** turns N consecutive array elements into a Variable Group */
auto toTuple (Chunk)(Chunk subArray) #nogc #safe pure nothrow
if (isInputRange!Chunk) { //Chunk must be indexable
VariableGroup nextLoopVariables; //fill the tuple with static foreach loop
static foreach(index; 0 .. N) {
static if ( isRandomAccessRange!Chunk ) { // add cases for other ranges here
nextLoopVariables[index] = subArray[index];
} else {
nextLoopVariables[index] = subArray.popFront();
}
}
return nextLoopVariables;
}
/** returns a range of VariableGroups */
auto byTuples(M array) #safe pure nothrow {
import std.algorithm.iteration : map;
static if(!isInputRange!M) {
static assert(0, "Cannot call map() on fixed-size array.");
// auto varGroups = array[].chunks(N); //fixed-size arrays aren't slices by default and cannot be treated like ranges
//WARNING! invoking "map" on a chunk range from fixed-size array will fail and access wrong memory with no warning or exception despite #safe!
} else {
auto varGroups = array.chunks(N);
}
//remove last group if incomplete
if (varGroups.back.length < N) varGroups.popBack();
//NOTE! I don't know why but `map!toTuple` DOES NOT COMPILE! And will cause a template compilation mess.
return varGroups.map!(chunk => toTuple(chunk)); //don't know if it uses GC
}
}
void main() {
testArrayToTuples([1, 3, 2, 4, 5, 7, 9]);
}
// Order of template parameters is relevant.
// You must define parameters implicitly at first to be associated with a template specialization
void testArrayToTuples(U : V[], V)(U arr) {
double[] randomNumbers = new double[arr.length / 2];
// generate random numbers
foreach(i, double x, double y; byTuples!2(arr).enumerate ) { //cannot use UFCS with "byTuples"
import std.random : uniform01;
randomNumbers[i] = (uniform01 * (y - x) + x);
}
foreach(n; randomNumbers) { //'n' apparently works despite shadowing a template parameter
import std.stdio : writeln;
writeln(n);
}
}
Using elementwise operations with the slice operator would not work here because uniform01 in uniform01 * (ends[] - starts[]) + starts[] would only be called once and not multiple times.
EDIT: I also tested some online compilers for D for this code and it's weird that they behave differently for the same code. For compilation of D I can recommend
https://run.dlang.io/ (I would be very surprised if this one wouldn't work)
https://www.mycompiler.io/new/d (but a bit slow)
https://ideone.com (it works but it makes your code public! Don't use with protected code.)
but those didn't work for me:
https://tio.run/#d2 (didn't finish compilation in one case, otherwise wrong results on execution even when using dynamic array for the test)
https://www.tutorialspoint.com/compile_d_online.php (doesn't compile the static foreach)

Swift : Recursively calling a function with an enum type as a parameter

I found this code at apple swift documentation
indirect enum ArithmeticExpression {
case Number(Int)
case Addition(ArithmeticExpression, ArithmeticExpression)
case Multiplication(ArithmeticExpression, ArithmeticExpression)
}
func evaluate(expression: ArithmeticExpression) -> Int {
switch expression {
case .Number(let value):
return value
case .Addition(let left, let right):
return evaluate(left) + evaluate(right)
case .Multiplication(let left, let right):
return evaluate(left) * evaluate(right)
}
}
// evaluate (5 + 4) * 2
let five = ArithmeticExpression.Number(5)
let four = ArithmeticExpression.Number(4)
let sum = ArithmeticExpression.Addition(five, four)
let product = ArithmeticExpression.Multiplication(sum, ArithmeticExpression.Number(2))
print(evaluate(product))
// prints "18"
i don't quit understand how the recursion is happening in here and why a constant declaration is being declared as a parameter in the return statement in the returning line ?
Think of it as a tree. Nodes=Expressions. Constants=Leaves.
(image source ruslanspivak.com)
While traversing it - you examine each of the two operands. If it's an expression, you need to compute it, so you call on 'evaluate' with this operand. If it's a constant, think of it like a result - it's just a number, so no more calculations are needed.
In the end, we ALWAYS get to a constants (=leaves) it is then when the the stack starts to fold and the values results return "up" in the tree to add up to the total result.
For more diving into the subject I recommend googling "binary expression tree".
(By the way, the code example does not tend for priorities. The multiplication is computed before the addition only because the order of calls.
If we really wanted to take care of priorities : e.g. "(", ")" over "*" , "/", a stack for operations would have been needed here.)

Switch statement in Swift

I'm learning syntax of Swift and wonder, why the following code isn't working as I expect it to:
for i in 1...100{
switch (i){
case 1:
Int(i%3) == 0
println("Fizz")
case 2:
Int(i%5) == 0
println("Buzz")
default:
println("\(i)")
}
}
I want to print Fizz every time number is divisible by 3 (3, 6, 9, 12, etc) and print Buzz every time it's divisible by 5. What piece of the puzzle is missing?
Note: I did solve it using the following:
for ( var i = 0; i < 101; i++){
if (Int(i%3) == 0){
println("Fizz")
} else if (Int(i%5) == 0){
println("Buzz")
} else {
println("\(i)")
}
}
I want to know how to solve this using Switch. Thank you.
The usual rules for the FizzBuzz game
are to replace every multiple of 3 by "Fizz", every multiple of 5 by "Buzz", and
every multiple of both 3 and 5 by "FizzBuzz".
This can be done with a switch statement on the tuple (i % 3, i % 5).
Note that _ means "any value":
for i in 1 ... 100 {
switch (i % 3, i % 5) {
case (0, 0):
print("FizzBuzz")
case (0, _):
print("Fizz")
case (_, 0):
print("Buzz")
default:
print(i)
}
}
Switch statements in Swift support value bindings.
This allows you to assign a value that matches a certain condition (evaluated via the where clause) to a temporary variable (x & y here):
for i in 1...100 {
switch (i){
case let x where x%3 == 0:
println("Fizz")
case let y where y%5 == 0:
println("Buzz")
default:
println("\(i)")
}
}
You could also use the assigned temp value in the case body.
Update:
Matt Gibson points out in the comments, that you can omit the assignment to a temp var if you are not going to use it in the case body.
So a more concise version of the above code would be:
for i in 1...100 {
switch (i){
case _ where i%3 == 0:
println("Fizz")
case _ where i%5 == 0:
println("Buzz")
default:
println("\(i)")
}
}
Side note: Your 2 code samples are slightly different (the first one uses the range 0-100 as input, while the second one operates on 1-100). My sample is based on your first code snippet.
This is a more general answer for people who come here just wanting to know how to use the switch statement in Swift.
General usage
switch someValue {
case valueOne:
// executable code
case valueTwo:
// executable code
default:
// executable code
}
Example
let someValue = "horse"
switch someValue {
case "horse":
print("eats grass")
case "wolf":
print("eats meat")
default:
print("no match")
}
Notes:
No break statement is necessary. It is the default behavior. Swift switch cases do not "fall through". If you want them to fall through to the code in the next case, you must explicitly use the fallthrough keyword.
Every case must include executable code. If you want to ignore a case, you can add a single break statement.
The cases must be exhaustive. That is, they must cover every possibly value. If it is not feasible to include enough case statements, a default statement can be included last to catch any other values.
The Swift switch statement is very flexible. The following sections include some other ways of using it.
Matching multiple values
You can match multiple values in a single case if you use separate the values with commas. This is called a compound case.
let someValue = "e"
switch someValue {
case "a", "b", "c":
// executable code
case "d", "e":
// executable code
default:
// executable code
}
You can also match whole intervals.
let someValue = 4
switch someValue {
case 0..<10:
// executable code
case 10...100:
// executable code
default:
// executable code
}
You can even use tuples. This example is adapted from the documentation.
let aPoint = (1, 1)
switch aPoint {
case (0, 0):
// only catches an exact match for first and second
case (_, 0):
// any first, exact second
case (-2...2, -2...2):
// range for first and second
default:
// catches anything else
}
Value Bindings
Sometimes you might want to create a temporary constant or variable from the switch value. You can do this right after the case statement. Anywhere that a value binding is used, it will match any value. This is similar to using _ in the tuple example above. The following two examples are modified from the documentation.
let anotherPoint = (2, 0)
switch anotherPoint {
case (let x, 0):
// can use x here
case (0, let y):
// can use y here
case let (x, y):
// can use x or y here, matches anything so no "default" case is necessary
}
You can further refine the matching by using the where keyword.
let yetAnotherPoint = (1, -1)
switch yetAnotherPoint {
case let (x, y) where x == y:
// executable code
case let (x, y) where x == -y:
// executable code
case let (x, y):
// executable code
}
Further study
This answer was meant to be a quick reference. Please read the full documentation for more. It isn't difficult to understand.
This is how it can be done
var i = 0
switch i {
case i where i % 5 == 0 && i % 3 == 0: print(" Fizz Buzz")
case i where i % 3 == 0 : print("Fizz")
case i where i % 5 == 0 : print("Buzz")
default: print(i)
}
The industry standard behaviour of switch can lead to bugs similar to "Go to Fail".
Basically the code doesn't always do exactly what it looks like the code will do when reading over it, which leads to code auditors skipping over critical bugs.
To counter that, Apple has decided switch statements should not work the same in Swift as the industry standard. In particular:
There is an automatic break at the end of every case. It's impossible for more than one case statement to execute.
If it's theoretically possible for one of the case statements to be missed, then the code will not compile at all. In swift one of the case statements will always execute, no matter what value is provided. If you provide an enum, every enum value must be handled. If a new value is added to an existing enum the code won't compile until new case statements are added. If you provide a 32 bit integer, you must handle every possible value of a 32 bit int.
Here are the two ways I use switch statement for this kind of problems .
1>> Using where keyword
func printNumberType(number : Int){
switch number {
case number where number % 3 == 0 && number % 5 == 0 :
print("foo bar")
case number where number % 3 == 0 :
print("foo")
case number where number % 5 == 0 :
print("bar")
default :
print("Number is not divisible by 3 and 5")
}
}
2>> Using values combination
func printNumberByMultipleValues(number : Int){
let combination = (number % 3,number % 5)
switch combination {
case (0,0):
print("foo bar")
case (0,_) :
print("foo")
case (_,0) :
print("bar")
default :
print("Number is not divisible by 3 and 5")
}
}
Here is closer example for multiple value type .
var printNumberByMultipleValues : (Int)->() = { number in
let combination = (number % 3,number % 5)
switch combination {
case (0,0):
print("foo bar")
case (0,_) :
print("foo")
case (_,0) :
print("bar")
default :
print("Number is not divisible by 3 and 5")
}
}
Use this code. Your logic is wrong. Your Switch Statement does not find the case accept 1 and 2
class TEST1{
func print() -> Void{
var i = 0
for i in 1...100{
if Int(i%3) == 0 {
println("Fizz")
}
else if Int(i%5) == 0{
println("Buzz")
}
else {
println("\(i)")
}
}
}
}
var x = TEST1()
x.print()

Resources