Mình đang cân nhắc nên dùng kí hiệu nào cho “not” hay “phần bù” trong ngôn ngữ của mình. May quá là mình vẫn còn vài kí hiệu một kí tự. 🙂
Giờ mình phải chọn toán tử cho “not” rồi.
(Kiểu dữ liệu được gọi là tập hợp trong ngôn ngữ của mình, nên khi mình nhắc đến “tập hợp” ở dưới thì hiểu là “kiểu dữ liệu cấu trúc” nhé)
Hầu hết/rất nhiều ngôn ngữ dùng dấu ngoặc nhọn dùng ! làm toán tử “not”. Ngôn ngữ khác thì dùng dấu ngã ~ hoặc kí tự khác.
Mình đang thiên về ! vì mình quen với C#, Java và các ngôn ngữ dùng dấu ngoặc nhọn khác.
Tuy nhiên, vì hướng đến tập hợp, mình đương nhiên có toán tử “là phần tử của” (∈). Ở đây mình chọn :, vì thế khai báo một biến sẽ có vẻ quen thuộc:
a : int
Giờ, mình cũng muốn có toán tử “không phải là phần tử của” (∉). Giải pháp rõ ràng là kết hợp kí hiệu “not” với kí hiệu “là phần tử của”:
name !: {“Alice”, “Bob”}
Ôi! Cái này nhìn ngon hơn nhiều (theo mình):
name ~: {“Alice”, “Bob”}
Nên mình đang phân vân: Có nên chọn cái quen thuộc (ít gây bất ngờ nhất) ! hay vì tính thẩm mỹ ~ hoặc lựa chọn nào khác?
Rõ ràng là kí hiệu phủ định phải được gõ được trên bàn phím thông thường. Là người không nói tiếng Anh bản ngữ, mình thường cảm thấy khó chịu vì người ta không để ý đến các ngôn ngữ và bàn phím không phải tiếng Anh. Trong tiếng mẹ đẻ của mình (tiếng Đan Mạch) thì ngay cả dấu ngã ~ cũng nằm ở “alt-gr”, cũng như ^ ¨ và cả , [, ], { and `}.
Mình biết là không thể chọn một tập hợp kí hiệu nào mà không có kí hiệu nào đó không phải là kí hiệu chính trên một số bàn phím ngôn ngữ cụ thể. Nên quy tắc mình tuân theo là bất kì kí tự nào phải là một phần của bộ kí tự ASCII 7-bit gốc, vì mình tin rằng bất kì bàn phím nào cũng cho phép gõ các kí tự này.
Ngôn ngữ của mình cũng cho phép lấy phần bù của kiểu dữ liệu. Mình định dùng cùng một kí hiệu cho cái này, vì nó liên quan đến cách định nghĩa kiểu dữ liệu (cú pháp tập hợp).
// Một tập hợp (kiểu dữ liệu) các chuỗi có độ dài từ 1 đến 30 AllowableNames = string ?.(Length >= 1 && Length <= 30) // Tập hợp các tên đã được dùng TakenNames = allowableNames && { “Alice”, “Bob” } // Tập hợp các tên được phép dùng mà chưa được dùng AvailableNames = AllowableNames & !TakenNames // Một “biến” có kiểu dữ liệu đó (phần tử của tập hợp) myNewName : AvailableNames
Định nghĩa của AvailableNames sử dụng phần bù của TakenNames. AvailableNames là kiểu dữ liệu (phụ thuộc) loại trừ các tên đã được dùng.
Có liên quan, mình cũng cần chọn toán tử (hoặc có lẽ là tên phương thức?) cho hàm nghịch đảo.
Xem xét hàm f:
f = float x -> x ^ 2
Thì mình cần một kí hiệu cho hàm nghịch đảo x ^ 2 -> x hoặc x -> x ^ 0.5. Chọn cú pháp nào đây, vì rõ ràng nó không phải là phủ định? Các lựa chọn khác:
g = ~~f g = !!f g = f inv g = inv f g = f.Inverse
Mình đã dùng dấu ngoặc kép cho phép ghép hàm (giống như trong F# và một số ngôn ngữ khác) như:
f >> g ≡ x -> g (f x) f << g ≡ x -> f (g x) x |> f ≡ x => f x f <| x ≡ f x





