from dataclasses import dataclass from typing import Callable def first_then_apply( strings: list[str], predicate: Callable[[str], bool], function: Callable[[str], object]) -> object: for item in strings: if predicate(item): return function(item) return None def powers_generator(*, base: int, limit: int): power = 1 while power <= limit: yield power power *= base def say(word: str | None = None, /): if word is None: return '' return lambda next=None: word if next is None else say(f'{word} {next}') def meaningful_line_count(filename: str, /) -> int: count = 0 with open(filename, 'r', encoding='utf-8') as file: for line in file: line = line.strip() if line and not line.startswith('#'): count += 1 return count @dataclass(frozen=True) class Quaternion: a: float = 0.0 b: float = 0.0 c: float = 0.0 d: float = 0.0 def __add__(self, q: 'Quaternion') -> 'Quaternion': return Quaternion(self.a + q.a, self.b + q.b, self.c + q.c, self.d + q.d) def __mul__(self, q: 'Quaternion') -> 'Quaternion': return Quaternion( q.a * self.a - q.b * self.b - q.c * self.c - q.d * self.d, q.a * self.b + q.b * self.a - q.c * self.d + q.d * self.c, q.a * self.c + q.b * self.d + q.c * self.a - q.d * self.b, q.a * self.d - q.b * self.c + q.c * self.b + q.d * self.a) @property def coefficients(self) -> tuple[float, float, float, float]: return (self.a, self.b, self.c, self.d) @property def conjugate(self) -> 'Quaternion': return Quaternion(self.a, -self.b, -self.c, -self.d) def __repr__(self) -> str: s = "" for c, unit in zip(self.coefficients, ["", "i", "j", "k"]): if c == 0: continue s += '-' if c < 0 else '' if s == '' else '+' s += '' if abs(c) == 1 and unit != "" else str(abs(c)) s += unit return '0' if s == '' else s
import { open } from "node:fs/promises" export function firstThenApply(strings, predicate, fun) { const first = strings.find(predicate) return first === undefined ? undefined : fun(first) } export function* powersGenerator({ ofBase: base, upTo: limit }) { for (let power = 1; power <= limit; power *= base) { yield power } } export function say(first) { if (first === undefined) { return "" } return (second) => { if (second === undefined) { return first } return say(`${first} ${second}`) } } export async function meaningfulLineCount(filename) { let count = 0 const file = await open(filename, "r") for await (const line of file.readLines()) { // Note that readLines will autoclose the file, yay const trimmed = line.trim() if (trimmed && !trimmed.startsWith("#")) { count++ } } return count } export class Quaternion { constructor(a, b, c, d) { Object.assign(this, { a, b, c, d }) return Object.freeze(this) } plus(q) { return new Quaternion( this.a + q.a, this.b + q.b, this.c + q.c, this.d + q.d ) } times(q) { return new Quaternion( q.a * this.a - q.b * this.b - q.c * this.c - q.d * this.d, q.a * this.b + q.b * this.a - q.c * this.d + q.d * this.c, q.a * this.c + q.b * this.d + q.c * this.a - q.d * this.b, q.a * this.d - q.b * this.c + q.c * this.b + q.d * this.a ) } equals(q) { return this.a === q.a && this.b === q.b && this.c === q.c && this.d === q.d } get conjugate() { return new Quaternion(this.a, -this.b, -this.c, -this.d) } get coefficients() { return [this.a, this.b, this.c, this.d] } toString() { let s = "" for (const [i, c] of this.coefficients.entries()) { if (c === 0) continue s += c < 0 ? "-" : s == "" ? "" : "+" if (Math.abs(c) !== 1 || i === 0) s += Math.abs(c) s += ["", "i", "j", "k"][i] } return s || "0" } }
function first_then_apply(array, predicate, fun) for _, s in ipairs(array) do if predicate(s) then return fun(s) end end return nil end function powers_generator(base, limit) local power = 1 return coroutine.create(function() while power <= limit do coroutine.yield(power) power = power * base end end) end function say(word) if word == nil then return "" end return function(next) if next == nil then return word else return say(word .. " " .. next) end end end function meaningful_line_count(filename) local count = 0 for line in io.lines(filename) do line = line:match "^%s*(.*)" if line ~= "" and line:sub(1, 1) ~= "#" then count = count + 1 end end return count end Quaternion = (function (class) local meta = { __add = function(self, q) return class.new(self.a + q.a, self.b + q.b, self.c + q.c, self.d + q.d) end, __mul = function(self, q) return class.new( q.a * self.a - q.b * self.b - q.c * self.c - q.d * self.d, q.a * self.b + q.b * self.a - q.c * self.d + q.d * self.c, q.a * self.c + q.b * self.d + q.c * self.a - q.d * self.b, q.a * self.d - q.b * self.c + q.c * self.b + q.d * self.a ) end, __eq = function(self, q) return self.a == q.a and self.b == q.b and self.c == q.c and self.d == q.d end, __tostring = function(self) local s = "" for i, c in ipairs(self:coefficients()) do if c ~= 0 then s = s .. (c < 0 and "-" or s == "" and "" or "+") s = s .. ((i ~= 1 and math.abs(c) == 1) and "" or tostring(math.abs(c))) s = s .. ({"", "i", "j", "k"})[i] end end return s == "" and "0" or s end, __index = { coefficients = function(self) return {self.a, self.b, self.c, self.d} end, conjugate = function(self) return class.new(self.a, -self.b, -self.c, -self.d) end }, } class.new = function (a, b, c, d) return setmetatable({a = a, b = b, c = c, d = d}, meta) end return class end)({})
Answer: The inventor of the null reference, Tony Hoare, said in 2009 that his invention was so easy to misuse that it has caused a billion dollars of damage up to that time. The very idea of a null reference is a rather disgusting hack. Think about it—the purpose of a reference is to be a value that refers to a value: You start with a value then make a reference to it. A null reference doesn’t reference anything, so where did it come from? What does a reference to nothing even mean? A null reference does not even reference a “nullish object”—it doesn’t reference anything at all. It just doesn’t even make sense. In fact, sadly, when you try to dereference a null reference, you get a runtime error or a system crash which is often difficult to debug. Of course, you can check if the reference is null before dereferencing it, but you know you are going to forget that check somewhere. What are the chances you are going to remember to guard every dereference check? We should not even be in the position of thinking about expecting a value but finding no value.
There’s more, of course. The article The worst mistake of computer science points out that null (1) subverts types, (2) is sloppy, (3) is a special case, (4) makes poor APIs, (5) exacerbates poor language decisions, (6) is difficult to debug, and (7) is non composable. That’s seven strikes against it.
Answer: It was just soooooooooo easy to implement. Humans often get lazy and love their shortcuts.
3**35 = 50031545098999710 but in Python 3**35 = 50031545098999707. Which one is right and which is wrong? Why? Explain exactly why the right value is right and the wrong value is that particular wrong value.
Answer: The Python result is correct because its integer representation is exact up to quantities of many tens of thousands of digits, while the JavaScript result is incorrect as it uses IEEE binary64 floating-point representation, which is only exact for integers up to $2^{53} - 1$. Beyond that, values are only approximations. In particular, if you try to represent 50031545098999707 in binary64, you can’t get it exactly. All you can get is:
The computation 3**35 accumulates rounding errors in JavaScript but got close, probably hitting 436637ed9b2612f4. The way JavaScript renders values that need more precision that it has is to use zeros in the places it does not know for sure.
{x: 3, [y]: 5, z}?
Answer: {'x': 3, y: 5, 'z': z}.
== operator “equals” (even though people do it all the time)?
Answer: You should not call this operator “equals” because it is not transitive. For example, "0x10" == 16, 16 == "16" but "0x10" != "16".
arithmeticsequence that accepts two arguments, start and delta, that returns a coroutine such that each time it is resumed it yields the next value in the arithmetic sequence starting with start and incrementing by delta.
Answer:
function arithmeticsequence(start, delta) return coroutine.create(function() local value = start while true do coroutine.yield(value) value = value + delta end end) end
var x = 1
function h() {var x = 9; return g();}
function f() {return x;}
function g() {var x = 3; return f();}
print f() * h() - x
Answer: (a) 0, (b) 2
Answer: Static scoping determines the bindings based on the lexical structure of the code, while shallow binding is all about bindings based on the most recent caller (which isn’t always known statically, at compile time). The two ideas are pretty much in opposition to each other.