How to Calculate Percentage Using % as a Postfix Unary Operator in Swift 3 and Still Be Able to Use % for Modulo

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 the
UIViewController 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



Leave a reply



Submit