Deprecated Functionality: usort(): Returning bool from comparison function is deprecated, return an integer less than, equal to, or greater than zero - return

Ran into a slight issue here below with some of my code.
// sorting
$sortField = $this->sortField;
$sortDir = $this->sortDir;
usort($data, function ($a, $b) use ($sortField, $sortDir) {
if ($sortDir == "asc") {
return $a[$sortField] > $b[$sortField];
} else {
return $a[$sortField] < $b[$sortField];
}
});
A bit confused here on what i need to change.
I read this in another thread.
PHP 8 introduced the Stable Sorting RFC, which (as it sounds) means that all sorting functions in PHP are now "stable".
The spaceship operator is used for comparing two expressions. It returns -1, 0 or 1 when $a is respectively less than, equal to, or greater than $b. Comparisons are performed according to PHP's usual type comparison rules.
So does this mean I need to add the spaceship operator here in the returns:
return $a[$sortField] <=> $b[$sortField];
} else {
return $a[$sortField] <=> $b[$sortField];
}
That is it?

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

Optional positional parameter in Dart

I'm studying recursion and I wrote this method to calculate the N° number of the Fibonacci series:
fibonacci(int n, Map memo) {
if (memo.containsKey(n)) return memo[n]; // Memo check
if (n <= 2) return 1; // base case
// calculation
memo[n] = fibonacci(n - 1, memo) + fibonacci((n - 2), memo);
return memo[n];
}
I think it doesn't need to be explained, my problem is just how to call this function from the main, avoiding providing an empty Map.
this is how I call the function now:
fibonacci(n, {});
But I would rather prefer to call it just like this:
fibonacci(n);
The canonical approach is to make memo optional, and use a fresh map if the memo argument is omitted. Because you want to change and update the map, you can't use a default value for the parameter, because default values must be constant, and constant maps are not mutable.
So, written very concisely:
int fibonacci(int n, [Map<int, int>? memo]) {
if (n <= 2) return 1;
return (memo ??= {})[n] ??= fibonacci(n - 1, memo) + fibonacci(n - 2, memo);
}
The ??= operator assigns to the right-hand side if the value is null.
It's used both to initialize memo to a new map if the argument was omitted,
and to update the map if a cached value wasn't present.
I'd actually reconsider using a map. We know that the Fibonacci computation will compute a value for every prior number down to 1, so I'd just use a list instead:
int fibonacci(int n, [List<int?>? memo]) {
if (n <= 2) return 1;
return (memo ??= List<int?>.filled(n - 2))[n - 3] ??=
fibonacci(n - 1, memo) + fibonacci(n - 2, memo);
}
That should work just like the map.
(I subtract 3 from n when doing the lookup because no value below 3 needs the list - it's handled by the prior if).
There are multiple ways to do it. This is my personal favorite, because it also limits the function that is only used for internal means and it doesn't have the need to check every recursion, as you already know there is a map provided:
int fibonacci(int n) {
return _fibonacci(n, {});
}
int _fibonacci(int n, Map<int, int> memo) {
if (n <= 2) return 1; // base case
final previouslyCalculated = memo[n]; // Memo check
if(previouslyCalculated != null) {
return previouslyCalculated;
}
// calculation
final next = _fibonacci(n - 1, memo) + _fibonacci((n - 2), memo);
memo[n] = next;
return next;
}
void main() {
print(fibonacci(4));
}
As Dart does not support overloading, if you actually need both versions to be publicly available (or want both private) you would have to pick different names.
Please note that I added proper types to your methods and cleaned them up a bit for everything that would not compile once proper types are used. Make sure you always use proper types and don't rely on dynamic to somehow works it's magic. The compiler can only help you, if you are explicit about what you want to do. Otherwise they can only nod and let you run into any mistake you may have made. Be smart, let your compiler help, it will catch a lot of errors for you at compile time that you would otherwise have to spent countless hours on debugging.
This is the solution I've found so far but looks very verbose and inelegant:
fibonacci(int n, [Map<int, int>? memo]) {
memo == null ? memo = {} : null; // null check
if (memo.containsKey(n)) return memo[n];
if (n <= 2) return 1;
memo[n] = fibonacci(n - 1, memo) + fibonacci((n - 2), memo);
return memo[n];
}
In this way I can call just:
fibonacci(n);

Match brackets the kotlin way

I'm giving Kotlin a go; coding contently, I have an ArrayList of chars which i want to classify depending on how brackets are matched:
(abcde) // ok characters other than brackets can go anywhere
)abcde( // ok matching the brackets 'invertedly' are ok
(({()})) // ok
)()()([] // ok
([)] // bad can't have different overlapping bracket pairs
((((( // bad all brackets need to have a match
My solution comes out(recursive):
//charList is a property
//Recursion starter'upper
private fun classifyListOfCharacters() : Boolean{
var j = 0
while (j < charList.size ) {
if (charList[j].isBracket()){
j = checkMatchingBrackets(j+1, charList[j])
}
j++
}
return j == commandList.size
}
private fun checkMatchingBrackets(i: Int, firstBracket :Char) : Int{
var j = i
while (j < charList.size ) {
if (charList[j].isBracket()){
if (charList[j].matchesBracket(firstBracket)){
return j //Matched bracket normal/inverted
}
j = checkMatchingBrackets(j+1, charList[j])
}
j++
}
return j
}
This works, but is this how you do it in Kotlin? It feels like I've coded java in Kotlin syntax
Found this Functional languages better at recursion, I've tried thinking in terms of manipulating functions and sending them down the recursion but to no avail. I'd be glad to be pointed in the right direction, code, or some pseudo-code of a possible refactoring.
(Omitted some extension methods regarding brackets, I think it's clear what they do)
Another, possibly a simpler approach to this problem is maintaining a stack of brackets while you iterate over the characters.
When you encounter another bracket:
If it matches the top of the stack, you pop the top of the stack;
If it does not match the top of the stack (or the stack is empty), you push it onto the stack.
If any brackets remain on the stack at the end, it means they are unmatched, and the answer is false. If the stack ends up empty, the answer is true.
This is correct, because a bracket at position i in a sequence can match another one at position j, only if there's no unmatched bracket of a different kind between them (at position k, i < k < j). The stack algorithm simulates exactly this logic of matching.
Basically, this algorithm could be implemented in a single for-loop:
val stack = Stack<Char>()
for (c in charList) {
if (!c.isBracket())
continue
if (stack.isNotEmpty() && c.matchesBracket(stack.peek())) {
stack.pop()
} else {
stack.push(c)
}
}
return stack.isEmpty()
I've reused your extensions c.isBracket(...) and c.matchesBracket(...). The Stack<T> is a JDK class.
This algorithm hides the recursion and the brackets nesting inside the abstraction of the brackets stack. Compare: your current approach implicitly uses the function call stack instead of the brackets stack, but the purpose is the same: it either finds a match for the top character or makes a deeper recursive call with another character on top.
Hotkey's answer (using a for loop) is great. However, you asked for an optimized recursion solution. Here is an optimized tail recursive function (Note the tailrec modifier before the function):
tailrec fun isBalanced(input: List<Char>, stack: Stack<Char>): Boolean = when {
input.isEmpty() -> stack.isEmpty()
else -> {
val c = input.first()
if (c.isBracket()) {
if (stack.isNotEmpty() && c.matchesBracket(stack.peek())) {
stack.pop()
} else {
stack.push(c)
}
}
isBalanced(input.subList(1, input.size), stack)
}
}
fun main(args: Array<String>) {
println("check: ${isBalanced("(abcde)".toList(), Stack())}")
}
This function calls itself until the input becomes empty and returns true if the stack is empty when the input becomes empty.
If we look at the decompiled Java equivalent of the generated bytecode, this recursion has been optimized to an efficient while loop by the compiler so we won't get StackOverflowException (removed Intrinsics null checks):
public static final boolean isBalanced(#NotNull String input, #NotNull Stack stack) {
while(true) {
CharSequence c = (CharSequence)input;
if(c.length() == 0) {
return stack.isEmpty();
}
char c1 = StringsKt.first((CharSequence)input);
if(isBracket(c1)) {
Collection var3 = (Collection)stack;
if(!var3.isEmpty() && matchesBracket(c1, ((Character)stack.peek()).charValue())) {
stack.pop();
} else {
stack.push(Character.valueOf(c1));
}
}
input = StringsKt.drop(input, 1);
}
}

Is it possible to define your own operators in Rascal?

I'm writing some test helper functions to make the output more sensible:
bool tstEq(first, second) {
if(first == second)
return true;
else {
println("<first> was not equal to <second>");
return false;
}
}
Is it possible to do something like this?
bool ===(first, second) = tstEq(first, second);
usage:
test bool myTest() = 1 === 2
Which would result in something like:
rascal>:test
1 was not equal to 2
bool: false
A short answer: no. I fully agree that this can be convenient (but may also lead to less readable code).
Given the large list of topics we want to address first, it is unlike that such a feature will come to Rascal in the near future.

How to mute jslint error on do{}while(false)

In this simple code:
do {
console.log('o');
} while (false);
jslint produces a warning on the last line saying Unexpected 'false'
I understand why, but I still want to mute it because in these cases that's how I want to have the control flow.
Let's look at what jslint expects in the while statement. From the source:
labeled_stmt('while', function () {
one_space();
var paren = next_token;
funct.loopage += 1;
advance('(');
step_in('control');
no_space();
edge();
this.arity = 'statement';
this.first = expected_relation(expression(0));
if (this.first.id !== 'true') {
expected_condition(this.first, 'unexpected_a');
}
no_space();
step_out(')', paren);
one_space();
this.block = block('while');
if (this.block.disrupt) {
prev_token.warn('strange_loop');
}
funct.loopage -= 1;
return this;
});
It mostly reads like English. 'while', one space, (, no space, expected expression, no space, ).
So let's look at what an expression(0) is. You can read through the source if you're really interested, but to be honest I can't really wrap my head around it either. Sorry. https://github.com/douglascrockford/JSLint/blob/master/jslint.js
As far as I can tell, though, expression(0) traverses the tree of operators and operands, and looks for values with a Right Binding Power greater than 0? And false has a binding power of 0? But variables and comparisons are okay here. I have no clue how that even works. Ask Crockford.
As for shutting up jslint, here is my suggestion:
/*jslint devel: true, continue: true */
var i = 0;
var forever = false;
do {
i = i + 1;
if (i < 5) {
continue;
}
console.log('o');
} while (forever);

Resources