How to calculate percentage using % as a postfix unary operator in Swift 3 and still be able to use % for modulo?
Just move
var percentage = 25%
under
postfix func % (percentage: Int) -> Double {
return (Double(percentage) / 100)
}
Like so
postfix operator %
postfix func % (percentage: Int) -> Double {
return (Double(percentage) / 100)
}
var percentage = 25%
Reason: your code would work in an app, but not in a playground, because a playground interprets the code from top to bottom. It doesn't see the postfix func
declaration located below var percentage
, so at the point of var percentage
it gives you an error, because it doesn't yet know what to do with it.
Member operator '%' must have at least one argument of type 'ViewController’
I declared the ’operator' at file scope
No, you didn't. You defined it in the scope of theUIViewController
definition:
postfix operator %
class ViewController: UIViewController {
// ...
static postfix func % (percentage: Int) -> Double {
return (Double(percentage) / 100)
}
}
One can define operators as static member functions of a type in Swift 3,
but only if they take at least one argument of that type.
Move the declaration to the file scope to fix the problem:
postfix operator %
postfix func % (percentage: Int) -> Double {
return (Double(percentage) / 100)
}
class ViewController: UIViewController {
// ...
}
Lesser than or greater than in Swift switch statement
Here's one approach. Assuming someVar
is an Int
or other Comparable
, you can optionally assign the operand to a new variable. This lets you scope it however you want using the where
keyword:
var someVar = 3
switch someVar {
case let x where x < 0:
print("x is \(x)")
case let x where x == 0:
print("x is \(x)")
case let x where x > 0:
print("x is \(x)")
default:
print("this is impossible")
}
This can be simplified a bit:
switch someVar {
case _ where someVar < 0:
print("someVar is \(someVar)")
case 0:
print("someVar is 0")
case _ where someVar > 0:
print("someVar is \(someVar)")
default:
print("this is impossible")
}
You can also avoid the where
keyword entirely with range matching:
switch someVar {
case Int.min..<0:
print("someVar is \(someVar)")
case 0:
print("someVar is 0")
default:
print("someVar is \(someVar)")
}
LALR(1) shift/reduce error using % for both percent and mod
The ambiguity you have here is between '%'
being a postfix operator and an infix operator. This is very similar to the common expression parser issue with '-'
being both a prefix and an infix operator, and you can solve it the same way with an explicit %prec
directive. The traditional way to write this would be:
%left '%' /* left-associative infix operator */
%nonassoc POSTFIX /* postfix operations are higher precedence */
%token VAL
%%
expr: expr '%' expr
| expr '%' %prec POSTFIX
| VAL
;
using precedence to solve both the associative ambiguity of infix-% and the precedence ambiguity between infix and postfix.
To solve it without the precedence rules, you need something like:
%token S_NUM O_PERCENT
%%
default: mod_term ;
mod_term: _mod_value
| _mod_value O_PERCENT mod_term ;
_mod_value: _mod_value O_PERCENT ;
| S_NUM
;
which makes the infix-% right associative instead of left associative. Unfortunately I see no way of solving this without using precedence rules that also makes infix-% left associative. This is due to the fact that you can't decide whether a given '%'
token is infix or postfix until you see the token after it, so the non-terminal before the '%'
needs to be the same for both rules (_mod_value
here or expr
in the %prec code)
handling Haskell operators as values
Thanks to Niklas' answer, I noticed that (**) has a different type than (^) and works with my simple operator list. After that I decided to write out short alternative definitions for div and mod, like so:
mod' :: Float -> Float -> Float
mod' a b = a - b * floor' (a / b)
div' :: (Num b, RealFrac a) => a -> a -> b
div' a b = fromIntegral $ truncate (a / b)
floor' :: Float -> Float
floor' a = fromIntegral $ floor a
Adding (**), (mod') and (div') to my list, the compiler compiled fine. (And since the operators are parsed from a string, they could keep their original names, too.)
What is strict mode and how is it used?
Its main purpose is to do more checking.
Just add "use strict";
at the top of your code, before anything else.
For example, blah = 33;
is valid JavaScript. It means you create a completely global variable blah
.
But in strict mode it's an error because you did not use the keyword "var" to declare the variable.
Most of the time you don't mean to create global variables in the middle of some arbitrary scope, so most of the time that blah = 33
is written it is an error and the programmer didn't actually want it to be a global variable, they meant to write var blah = 33
.
It similarly disallows a lot of things that are technically valid to do. NaN = "lol"
does not produce an error. It also doesn't change the value of NaN. Using strict this (and similar weird statements) produce errors. Most people appreciate this because there is no reason to ever write NaN = "lol"
, so there was most likely a typo.
Read more at the MDN page on strict mode.
Related Topics
Change Ncwidgetdisplaymode Programmatically in iOS10 Widget
Swift Select All Photos from Specific Photos Album
How to Hide API Keys in Github for iOS (Swift) Projects
Why am I Getting Com.Facebook.Sdk.Login Error 308
Swift Core Data Sync with Web Server
Masked Uivisualeffectview Does Not Work on iOS 10
iOS Swift Connect Wifi Programmatically and Distinguish Between Bad Password and No Wifi in Range
How to Get the Nondecoded Attributes from a Decoder Container in Swift 4
3D Touch Quick Actions Not Working at All
How to Check If Device Orientation Is Landscape Left or Right in Swift
Xcode 12.5 Missing Entitlement Com.Apple.Developer.Associated-Appclip-App-Identifiers
How to Convert Data Dictionary into an Array Swift
iOS Swift Nsmutabledata Has No Member Appendstring
Using Static Libraries with Cocoapods 1.5 No Such Module at Import
How Posting One Signal Notification's Additional Data and Receiving That
Could Not Build Module 'Nanopb' Error in Xcode 12.0.1
How to Delete an Image from Photolibrary After I Pick It Up Using Uiimagepickercontroller