askql icon indicating copy to clipboard operation
askql copied to clipboard

What features and functionalities is AskScript missing?

Open czerwinskilukasz1 opened this issue 4 years ago • 4 comments

I tried to translate a couple of Javascript scripts to AskScript and often I get blocked on some missing resources or language constructs. This ticket will list them all.

czerwinskilukasz1 avatar Jul 17 '20 11:07 czerwinskilukasz1

Example 1.

I wanted to translate the following program from Javascript to AskScript and got blocked.

Javascript:

const sum_pairs = function (ints, s) {
  const leftMostPosition = {};
  for (let i = 0; i < ints.length; ++i) {
    const a = ints[i];
    if (!(a in leftMostPosition)) {
      leftMostPosition[a] = i;
    }
  }
  
  for (let i = 0; i < ints.length; ++i) {
    const b = ints[i];
    const a = s - b;
    if (a in leftMostPosition && leftMostPosition[a] < i) {
      return [a, b];
    }
  }
};

I bumped into the following problems:

  • in construct (or an equivalent) is missing (filed it as: https://github.com/xFAANG/askql/issues/400). I bypassed it by comparing with null, which would work in this case but wouldn't work if I had null values in the map.
  • the is no way to change value in a map (meaning: to create a new map with an updated key), set doesn't work; it's filed as: https://github.com/xFAANG/askql/issues/257

The current status of the AskScript code is:

// Below is a complete solution for a 5kyu Codewars task: 
// https://www.codewars.com/kata/54d81488b981293527000c8f
ask {
  const sumPairs = fun (ints:array(int), s:int) {
    let leftMostPosition: map(int) = {};
    for (const i = 0; i < ints.length; i=i+1) {
      const a = ints[i];
      if (leftMostPosition[a] == null) {
        leftMostPosition = set(leftMostPosition, a, i);
      }
    }
    
    for (const i = 0; i < ints.length; ++i) {
      const b = ints[i];
      const a = s - b;
      if ((leftMostPosition[a] != null) && (leftMostPosition[a] < i)) {
        return [a, b];
      }
    }
  }

  [
    sumPairs([11, 3, 7, 5],         10)  == [3, 7],
    sumPairs([4, 3, 2, 3, 4],        6)  == [4, 2],
    sumPairs([0, 0, -2, 3], 2)           == null  ,
    sumPairs([10, 5, 2, 3, 7, 5],   10)  == [3, 7]
  ]
}

czerwinskilukasz1 avatar Jul 17 '20 11:07 czerwinskilukasz1

Very interesting experiment, @czerwinskilukasz1! Couple points:

  • why not use forOf here for iterating arrays?
  • {} is a different type in JavaScript than a map, I'm not sure if we need to make the same distinction
  • if we make it so that for returns a value your program will need to have explicit return empty at the end

What can be done to improve the simplicity and readability of your solution when coded in AskScript. What are the parts that you like and dislike?

mhagmajer avatar Jul 17 '20 14:07 mhagmajer

Very interesting experiment, @czerwinskilukasz1! Couple points:

  • why not use forOf here for iterating arrays?

Simply I wanted to change as little code as possible.

  • {} is a different type in JavaScript than a map, I'm not sure if we need to make the same distinction

Currently the only associative type in AskScript is map. There is no object, record or any other similar type.

  • if we make it so that for returns a value your program will need to have explicit return empty at the end

Good point. The tests will catch it.

What can be done to improve the simplicity and readability of your solution when coded in AskScript. What are the parts that you like and dislike?

Two things I would improve, based on this program:

  1. I needed to change ++i to i=i+1, which was a bit disturbing.
  2. The need to write brackets that separate different operators in if ((leftMostPosition[a] != null) && (leftMostPosition[a] < i)) { disturbed me too.

czerwinskilukasz1 avatar Jul 17 '20 20:07 czerwinskilukasz1

Example 2.

I wanted to translate the following Javascript example to AskScript and needed to write more lines of code when using cache. (Also, hasKey would be useful, but I mentioned it already in Example 1, and push would be nice to have too)

Javascript:

var fibonacci = function(n, cache) {
    if (typeof cache === 'undefined') {
      cache = [0, 1];
    }
    
    if(n==0 || n == 1)
        return n;
    
    if(n < cache.length)
      return cache[n];
    
    const result = fibonacci(n-1, cache) + fibonacci(n-2, cache);
    cache.push(result);
    return result;
}

AskScript:

ask {
    const fibonacci = fun(n:int, cache:array(int)) {
        if (cache:length == 0) {
          cache = [0, 1];
        }
        
        if ((n==0) || (n == 1)) {
            return [n, cache];
        }
        
        if(n < cache:length) {
          return [cache[n], cache];
        }
        
// === Here is where more lines are needed because all variables in AskScript are immutable.

        const res1 = fibonacci(n-1, cache);
        cache = res1[1];

        const res2 = fibonacci(n-2, cache);
        cache = res2[1];

        const result = res1[0] + res2[0];
        cache = cache:set(n, result);
        return [result, cache];
// === ===
    }
    
    [
        fibonacci(0, [])[0],
        fibonacci(1, [])[0],
        fibonacci(2, [])[0],
        fibonacci(3, [])[0],
        fibonacci(4, [])[0],
        fibonacci(5, [])[0],
        fibonacci(6, [])[0]
    ]
}

czerwinskilukasz1 avatar Jul 17 '20 20:07 czerwinskilukasz1