Friday, November 13, 2020

Finally, C# 9 record, the equivalent of Scala's case class

While C# is a wonderful programming language, there is something that I would like to see to make our life programmer easier. If you are familiar with the Scala programming language you would know about "case class". 

Object Comparison

The case class in Scala is designed to support immutable data modeling. It provides object comparison out of the box without you need to compare each property in the object. For example in C# you have a Person class as below:

Thursday, October 8, 2020

Writing the correct object equality

 While working with scala, object equality is a very important feature that we get for free while in the other programming languages such as C# or Java is quite challenging to implement. In scala, there is the case class, which is just like a normal class but is used to represent data only, it just like POJO in Java or POCO in C#.

Today, I came across an interesting article written by:

Martin Odersky is the creator of the Scala language. As a professor at EPFL in Lausanne, Switzerland, he works on programming languages, more specifically languages for object-oriented and functional programming. His research thesis is that the two paradigms are two sides of the same coin, to be unified as much as possible. To prove this, he has experimented with a number of language designs, from Pizza to GJ to Functional Nets. He has also influenced the development of Java as a co-designer of Java generics and as the original author of the current javac reference compiler. Since 2001 he has concentrated on designing, implementing, and refining the Scala programming language.

Lex Spoon is a software engineer at Google, Inc. He worked on Scala for two years as a post-doc at EPFL. He has a Ph.D. in computer science from Georgia Tech, where he worked on static analysis of dynamic languages. In addition to Scala, he has worked on a wide variety of programming languages, ranging from the dynamic language Smalltalk to the scientific language X10. He and his wife currently live in Atlanta with two cats, a chihuahua, and a turtle.

Bill Venners is president of Artima, Inc., publisher of the Artima Developer website (www.artima.com). He is the author of the book, Inside the Java Virtual Machine, a programmer-oriented survey of the Java platform's architecture and internals. His popular columns in JavaWorld magazine covered Java internals, object-oriented design, and Jini. Active in the Jini Community since its inception, Bill led the Jini Community's ServiceUI project, whose ServiceUI API became the de facto standard way to associate user interfaces to Jini services. Bill is also the lead developer and designer of ScalaTest, an open-source testing tool for Scala and Java developers.

Enjoy the article below:

https://www.artima.com/lejava/articles/equality.html



Tuesday, June 16, 2020

SBT Troubleshoot: Error on SBT Scala Compilation Because of Incompatible Java Version

Have you ever getting this kind of problem when trying to run your SBT command to compile your Scala code?


$ sbt compile
[info] Done updating.
error: error while loading String, class file '/modules/java.base/java/lang/String.class' is broken
(class java.lang.NullPointerException/null)
[error] java.io.IOError: java.lang.RuntimeException: /packages cannot be represented as URI
[error]         at java.base/jdk.internal.jrtfs.JrtPath.toUri(JrtPath.java:176)
[error]         at scala.tools.nsc.classpath.JrtClassPath.asURLs(DirectoryClassPath.scala:204)




Usually, this problem happens the first time you set up your project on your computer. This happens because you're using an incompatible Java version to compile your scala code. You can check the scala to Java compatibility in this page https://docs.scala-lang.org/overviews/jdk-compatibility/overview.html

Now, how can you fix this? You need to find out which Java version is being used by SBT and then set the correct one to use. Do you try to use java -version command?

$ java -version



While the java -version command helps you telling which java is being used by your system, SBT might use a different version. For SBT specific, you can use sbt -J-showversion command as follow:

$ sbt -J-showversion
openjdk version "1.8.0_192"
OpenJDK Runtime Environment (Zulu 8.33.0.1-macosx) (build 1.8.0_192-b01)
OpenJDK 64-Bit Server VM (Zulu 8.33.0.1-macosx) (build 25.192-b01, mixed mode)



After knowing your Scala compatibility and your SBT's Java version you can follow any of these solutions in this page https://users.scala-lang.org/t/telling-sbt-to-use-different-jdk-version/4608/10

I hope this helps anyone having a similar problem.

Wednesday, March 11, 2020

Tips: Dealing with joda time LocalDate comparison in scala using implicit class

If you are coming from C#, working with DateTime is pretty straight forward. You can compare equal, greater than, less than, or getting the day difference from two dates without any hassle. But if you are in Scala, using joda time, it's not easy to get it right at the right for the first time. the LocalData has several functions can be used to compare the date-time. They are isAfter, isEqual, isBefore, and daysBeetween to get the diff of the day.

Here is my favorite approach to deal with joda time LocalDate comparison. First, we need to create an implicit class. In C#, this is comparable to the Extension Method. We can add or extend the functionality of a class without modifying the class implementation. In this case, we will extend LocalData as below:

----------------------
import org.joda.time.{Days, LocalDate}
object LocalDateExtension {   class LocalDateExtension(a: LocalDate) {     def dayDiff(b: LocalDate): Int = {       Days.daysBetween(a, b).getDays.abs     }
    def >(b: LocalDate): Boolean = {       a.isAfter(b)     }
    def >=(b: LocalDate): Boolean = {       a.isAfter(b) || a.isEqual(b)     }
    def <(b: LocalDate): Boolean = {       a.isBefore(b)     }
    def <=(b: LocalDate): Boolean = {       a.isBefore(b) || a.isEqual(b)     }   }
  implicit def extendLocalDate(a: LocalDate) = new LocalDateExtension(a) }
------------------------

What we are doing here? In scala, we are allowed to name a method using any character such as equal, greater than, or less than signs. This way, we can use the same syntax we use in C# to compare dates. For example as below:

----------------------
import org.joda.time.{Days, LocalDate}
val a = LocalDate("2010-04-28") val b = LocalDate("2010-04-29")
print(a > b) // false print(a >= b) // false print(a < b) // true print(a <= b) // true
------------------------


Tuesday, April 2, 2019

Tips: Using SSL locally with Webpack Dev Server (via create-react-app)

I would share this for anyone interested in running a create-react-app generated app with local dev using SSL.
Webpack Dev Server checks the .env file in the root of the project for any environment variables - so you can add the following line to the file:
HTTPS=true
Now when you run the application with npm start a localhost self-signed certificate will be generated and issued.
Chrome will complain that the certificate is not valid - for which you can do either of the following:
1. Enable invalid certificates for localhost by setting the Chrome flag here (paste into the URL box): 
chrome://flags/#allow-insecure-localhost
OR...
2. Import the certificate to you Trusted Root Authorities certificate store...
First, save the certificate:
Visit the localhost dev server in Chrome, click the Not Secure warning and click the Certificate (invalid) button.
Select Details tab, and then Copy to File (I think it is labelled Export on Mac - I am on Windows).
Save the file as localhost.cer , and note the location - maybe in your project folder is a good location.
To import the Certificate (in Windows... I am sure its easy on MacOS too):
Now you need to import the certificate to the Trusted Root Certification Authorities store. For Windows, you can just double click on the localhost.cer file you saved, and choose to import for Local Machine, and then ensure you import to the Trusted Root Certification Authorities store, as mentioned.
Restart Chrome, and now you can test using SSL on localhost :-) So you can now do the PWA tests without needing to upload to a server first.
One last thing - Chrome now has Lighthouse built in so there is no need to install an extra extension - you can just select it from the Audits tab in Chrome DevTools

Sunday, August 19, 2018

Tips: How to ssh to your Digitalocean server without password

If you are tired of being asked for a password when accessing your remote droplet servers in Digitalocean, you might consider adding an rsa public key to your server so you don't need to input password anymore to ssh to your server.

Here are some useful tips that I have:

The hard way

1. Create a pair of rsa private and public key in your computer.


  • To create a pair of rsa private and public key, in a Mac computer,  in your home directory, you can go to .ssh directory by typing:
$ cd ~/.ssh
  • Once you are in the .ssh directory, you can create the pair of rsa private and public key using the following command:
$ ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
  • You will be given a choice to overwrite your current id_rsa file or you can choose to create a new file. I personally want to create a new file for example id_rsa_do.
  • If you execute ls command in your .ssh directory, you would notice there will be two new files id_rsa_do and id_rsa_do.pub. It means your ssh-keygen command is working fine.

2. Copy your public key and login to your droplet

  • After creating the private and public key, you might want to copy your public key to and login to your droplet.
  • Go to your .ssh directory and execute 
$ cat id_your_rsa.pub
  • You can copy the content of that file and then login to droplet server. You will still need to provide the password at this step
$ ssh root@your_ip_address
  • Once you are in the remote server, you can go to the .ssh directory by using the same command:
$ cd ~/.ssh

3. Add your public key to .ssh/authorized_keys

  • Once you are in the remote server's .ssh directory, you can execute the following command (it will open nano editor):
$ nano authorized_keys
  • You can paste your public key in this file and then exit and save.
  • You can exit your remote server and back to your local computer's terminal.

4. Try ssh without password

  • You can try ssh-ing again to your remote server using the same command:
$ ssh root@your_ip_address
  • If still not working, and if you're having multiple ssh keys, you can specify the private key you want to use by using the following command:
$ ssh -i /path/to/private/key username@your_ip_address

OR

$ ssh-add /path/to/private/key
$ ssh username@your_ip_address

The easy way

You can follow this official tutorial from Digitalocean to add ssh key from their GUI.



Source:


Tuesday, October 31, 2017

Text Editor Tips: Some Useful Brackets Extension

Brackets is an open source and free-to-use text editor and primarily being used by web developers and designer. I mainly use Brackets for doing the web front-end development. I fell in love with the built-in live preview feature.

Here are some extensions that I found really useful:


I will update this post if I find more

Sunday, July 9, 2017

Scala levels: beginner to expert, application programmer to library designer

This is a good reference for someone who wants to be a library designer. I see that the original website of article (here) is no longer be maintained. So, I put this on my blog so other still can read this. Please enjoy.


Scala is a bit of a chameleon. It makes many programming tasks refreshingly easy and at the same time contains some pretty intricate constructs that allow experts to design truly advanced typesafe libraries. This means that, depending at what piece of code you look at, Scala might look very simple or very complex. But which pieces exactly are easy for beginners and which are more advanced?  In the end, everybody will have their own yardstick. Nevertheless, I am trying here to give a rough categorization.
I hope this will help newcomers to the language decide in what order to pick subjects to learn, and that it will give some advice to teachers and book authors in what order to present the material.
I assume that programmers have already a good knowledge of Java, so we can take at least pre-generics Java 1.4 for granted. If that's not the case, some of the entry-level concepts such as classes and exceptions would need to be moved to more advanced levels.

Also, I distinguish between Scala application programmers and Scala library designers, because the required skill sets are really quite different. A first shot at a categorization has been discussed last month on the scala-debate mailing list.The current categorization incorporates some of the suggestions that were made then. So, here we go:
Level A1: Beginning application programmer
  • Java-like statements and expressions: standard operators, method calls, conditionals, loops, try/catch
  • class, object, def, val, var, import, package
  • Infix notation for method calls
  • Simple closures
  • Collections with map, filter, etc
  • for-expressions
Level A2: Intermediate application programmer
  • Pattern matching
  • Trait composition
  • Recursion, in particular tail recursion
  • XML literals
Level A3: Expert application programmer
  • Folds, i.e. methods such as foldLeft, foldRight
  • Streams and other lazy data structures
  • Actors
  • Combinator parsers
Level L1: Junior library designer
  • Type parameters
  • Traits
  • Lazy vals
  • Control abstraction, currying
  • By-name parameters
Level L2: Senior library designer
  • Variance annotations
  • Existential types (e.g., to interface with Java wildcards)
  • Self type annotations and the cake pattern for dependency injection
  • Structural types (aka static duck typing)
  • Defining map/flatmap/withFilter for new kinds of for-expressions
  • Extractors
Level L3: Expert library designer
  • Early initializers
  • Abstract types
  • Implicit definitions
  • Higher-kinded types
As I wrote above, the skill sets required from application programmers and library designers are really quite different. But if I should throw them into the same baskets, I would group like this:
  • A1, A2/L1, A3/L2, L3
That is, intermediate application programming is about on the same level of difficulty as junior library design, and advanced application programming is on the same level as senior library design.
To clarify: One can program very productively in Scala on level A1, which one should be able to pick up in a day or so, coming from Java. Mastering A2 will doubtlessly increase programmer productivity. A3 is for expert programmers with more specialized tasks, not everyone needs to get to that level. The same holds for library design. There are great libraries designed with the tools on level L1 and L2. Some libraries require L3 elements such as implicits and higher-kinded types, but a library does not automatically get better if it uses these elements -- often the opposite is true.



Sunday, April 30, 2017

Game Development: Text 101 - Text Based Game With Finite State Machine

This time, I've created a really simple text based game that allow the player to progress state to another state by choosing some options. Some options might take the player to the final state of the story and that's where the game end.

A. What I learnt from this course session are:

1. Importing image assets 

To import an image asset, we just need to drag and drop the image from your directory explorer to the asset panel. And if you're working on a 2D game make sure the texture type is "Sprite (2D and UI)" by selecting the image asset in the asset panel and checking the texture type in the inspector.
Unity Game Development - Checking Texture Type in Inspector Panel


2. Adding GameObject to the scene 

In this game, I'm using game object called UI Text. UI Text is an object to display text in the game. To add UI Text: Open Game Object menu -> UI -> Text
Unity Game Development - Adding UI Text GameObject
Unity Game Development - Adding UI Text to Game Scene


3. Toggle layers

In Unity's Game Scene, there are several layers that you can toggle to be visible/invisible. You can find that toggle in the top right corner of Unity.
Unity Game Development - Toggle Layers

4. Canvas

Canvas is where all the game will be operating in. So if you put GameObject such as Text UI outside canvas, that object won't be visible during game play mode.

5. Interacting with GameObjects in Scene Panel 

In the upper-left of unity you can find some useful tools to interact with game object on the scene. Those tools are Hand (Shortcut Q), Move (Shortcut W), Rotate (Shortcut E), Scale (Shortcut R), and UI tool (shortcut T).

Unity Game Development - Tools to Interact with Game Objects

6. Setting camera background color

The camera uses blue as its default background color. We can change it easily just by selecting the Main Camera object in the Hierarchy and change the background color from the inspector panel. In this case, I changed the background color to be black.

7. Add a new component/script to UI Text object

If you want to give your UI text a behavior you can add a script to your game object. One way to add a script is:

1. Select your game object from Hierarchy (In case of my game, it is a UI Text object).
2. Go to your inspector panel and scroll to the bottom. You will find add component button on the bottom.
Unity Game Development - Add Component/Script to Game Object
3. If you want to use existing script, choose "Scipts". But if you want to create new script, choose "New Script".

8. Properties in a assets class will be accessible trough inspector

In order to access your UI Text in your code, you need to create a property in your class for example:

Then to connect your property to the Game Object, you need to select your UI Text object from Hierarchy and then check your inspector (but before that you need to add script to your game object). From the inspector, you'll find a Text Controller (Script) component, and you can set the Text property to the UI Text object as seen in screen capture below.

Unity Game Development - Connecting Text Property to UI Text Game Object

9. There are two main views in Unity (Scene View and Game View)

As you build your game, you can switch from the Scene View to the Game View to preview how it will look in its platform-specific final build. Learn how to preview and test your game as you work. That makes it really fast and easy to try things out.

What are scenes and Game Objects?
You can think of a scene as a level of your game (but it could also be another element, like a main menu, for example). Game Objects are the environment, cameras, lights, and all the other elements in the scene.

Tips:


  • To get into the center of game object: go to Hierarchy -> double clicks on the game object and you will see your game object in the scene view
  • We can connect game object to the script by creating a public property in the script and then connect that property with GameObject by simply choosing from the inspector.

B. Developing Text 101

In the game development process itself, we are using what we call the Game Design Document (GDD). GDD is a document that outlines our game and its screens. We also learn about Finite-state machine (FSM). FSM is an abstract machine that can be in exactly one of a finite number of states at any given time. It can change from one state to another in response to external inputs.

Game State Diagram

Unity Game Development - State Diagram 1

Unity Game Development - State Diagram 2
In order to transition between states, player need to press a key represent by the state. For example in the first state diagram, player starts in a "cell" state. If the player press "M" key, the player will go to "mirror" state. In code, each state is represented by enum as shown in snippet of code below.

In Update() method, we handle all currentState of the player and create methods to handle the state transition. You might get an idea by looking at this snippet of code.


These are some screenshots of my game. In first screenshot, you can see when the player in the "cell" state and then transitioning to the second state Mirror by pressing M.

Unity Game Development - Player in First "cell" State

Unity Game Development - Player in Second "mirror" State
If you are interested of making this kind of game please take a look at my Github repo below for a complete code:
https://github.com/ibanezang/text101

You can just clone the code and run it on your local machine. I hope you enjoy reading my writing. Can't wait to share more about my game development journey! Thank you.

Game Development: Adding .gitignore File to Unity Repository

I'm using git as my version control for my unity projects. In my second project, I have problem with vast amount of file changes generated by Unity because I forgot to add the .gitignore to my repository. In this post, I want to describe two ways of adding the correct .gitignore file to you unity project's repository.

1. Via Github Web Interface 

When working with my Number Wizard game project, I created the git repository via Github web interface and I can choose to add .gitignore from the Add gitignore dropdown list.

Unity Game Development - .gitignore via Github web interface

2. Add .gitignore For Existing Project

As I mentioned above, in my Text 101 project, I had a problem that git track all Unity's generated files as changes. Each time I changed something in the game scene, it generated thousands tracked changes by git. Here is my solution to that problem:

1. Find the correct gitignore file from this link. For Unity, I'm using this file.

2. Go to your repository folder/directory and create ".gitignore" file in the root of your repo folder.
In windows you can just create and empty file or in Mac you can use "touch .gitignore". In Linux or Mac based system, ".gitignore" file by default would be hidden. You can use "ls -a" to see your file or you can follow this simple tutorial to show hidden files on Mac.

3. Open your empty ".gitignore" file and paste this content and save the change:

4. Run the following commands on you terminal:

  • git rm -r --cached . 
  • git add . 
  • git commit -m ".gitignore is now working"

Please be aware on the first and second commands there is [dot] character there.

Actually this solution works for any gitignore files do you want to add to your repository. If you find this tutorial useful, please leave a comment bellow. Thank you.

Monday, April 3, 2017

Game Development: Text Based Game "Number Wizard"

The online course I've taken were introducing the feature available in Unity using a very simple text based game. The game was called "Number Wizard".

What I learnt from this game were:


  1. How to change the layout of Unity's panels.
  2. Unity's folder structure.
  3. Unity's scene and objects.
  4. How to print logs into Unity's console using print() method.
  5. Unity's game application flow.
    • We can attach a script to an object.
    • That script inherited MonoBehaviour
    • It has Start() method that will be called once in the beginning
    • There is Update() method that will be called once per frame.
  6. How to get input from keyboard.

While all those points are very obvious and basic, I think it is a good start to get to know them all in the beginning of this journey. So it will be a good foundation for me to go faster later.

About Number Wizard

Number Wizard is a game to guess player's number in mind.
Here is the game play of the game:

  1. Player just need to think about one number between 1-10000.
  2. The game will guess with a number.
  3. The player need to answer whether that guess higher, lower, or equal.
  4. If it is still not equal, the game will guess again until find the number of the player have in mind.

The Game implementation

The player can interact with the game using up arrow (tell the guess is higher), down arrow (tell the guess is lower), or space (tell the guess is equal). The game will end if the player press space key. The complete implementation of player's interaction can be seen in line 29-44.


To find the number, we need to implement binary search by calculating the middle value of min and max bound as you can see in FindMid() method in line 64.

You can see the complete project in this  repository of mine:
https://github.com/ibanezang/NumberWizardGames

Please leave comment and suggestion if you find this post interesting. Thank you :)

Wednesday, October 5, 2016

Ubuntu Troubleshoot: Fixing missing and flickering mouse cursor

After fresh install Ubuntu I found that sometimes my mouse cursor is missing and flickering so much. In order to solve this problem we need to disable unknown displays settings as explained below.

1. Open Displays settings from Ubuntu Start Menu.

Open Displays Settings

2. If you are lucky you will see two rectangles shape in the Displays window (red and green). Click on the green colored rectangle with "Unknown Display" on it, as seen below.

Displays Settings "Unknown Display"

3. As you can see in previous image, the Unknown Display is turned on. Click on the switch to turn it off. Then click on "Apply" button.

Turned off Unknown display

That's how I fixed my problem with the mouse cursor. If you find this tips helpful, please leave a comment below. Thank you :)


Ubuntu Tips: Startup Application - Case study enabling touchpad edge scrolling and two fingers scrolling

Today, I want to share a really handy feature in Ubuntu, Startup Application. Startup Application allows you to run additional script or program during the operating system startup. The use case that it can help you are numerous. From mount your drives or devices, startup your development web server, or maybe more complex repetitive tasks that you need to run manually every time you sign into your Ubuntu.

I will show a use case that I personally use in my Ubuntu and this is will be very helpful if you fresh install Ubuntu in your laptop. The use case is to enable edge scrolling and two finger scrolling on your laptop's Synaptics Touchpad. To enable those two features you need to run following commands in your terminal (to open your terminal press ctrl + alt + t):

$ synclient VertEdgeScroll=1 
$ synclient VertTwoFingerScroll=1

If you run those commands you can see that they work perfectly enabled your edge scrolling and two finger scrolling. But the problem is the effect of those commands will wear off every time you restart/shutdown your computer so you need to run those commands again and again. This is the time for Startup Application will help you!

Ok, here is how I use Startup Application:

First Step:
1. Create a bash script called scrolling inside /bin/ directory by running following command in your terminal:

$ sudo gedit /bin/scrolling

2. That command will open a text editor and you need to copy this as its content:

#!/bin/bash 
synclient VertEdgeScroll=1 
synclient VertTwoFingerScroll=1

3. Save and close that file.

Second Step:
Make sure you change  the type of that scrolling file into excutable using this command:

$ sudo chmod +x /bin/scrolling

Last Step:
1. Open Startup application from Ubuntu Start menu.


Open Startup Application in Ubuntu
2. Once opened you will see something like this.

View of Startup Application Preferences

3. Click "Add" and enter the following information as in the image below then click "Add".

Name: Scrolling
Command: /bin/scrolling
Comment: Enable two fingers scrolling and edge scrolling

Add Startup Program

4. Close the Startup Application


That's all you have to do, it's easy and you can try restart your computer to see the result. :D

If you find this is helpful or do you have something in mind you want to try with Startup Application? Please share your experience in the comment. Thank you :)

Sunday, August 21, 2016

Copy from dRPC documentation: gRPC Motivation and Design Principles.

I noticed that the motivation and design principles of gRPC is no longer available in the original source. So I copied this documentation for anyone interested in it. Please enjoy.

Motivation

Google has been using a single general-purpose RPC infrastructure called Stubby to connect the large number of microservices running within and across our data centers for over a decade. Our internal systems have long embraced the microservice architecture gaining popularity today. Having a uniform, cross-platform RPC infrastructure has allowed for the rollout of fleet-wide improvements in efficiency, security, reliability and behavioral analysis critical to supporting the incredible growth seen in that period.

Stubby has many great features - however, it's not based on any standard and is too tightly coupled to our internal infrastructure to be considered suitable for public release. With the advent of SPDY, HTTP/2, and QUIC, many of these same features have appeared in public standards, together with other features that Stubby does not provide. It became clear that it was time to rework Stubby to take advantage of this standardization, and to extend its applicability to mobile, IoT, and Cloud use-cases.

Principles & Requirements


Services not Objects, Messages not References - Promote the microservices design philosophy of coarse-grained message exchange between systems while avoiding the pitfalls of distributed objects and the fallacies of ignoring the network.

Coverage & Simplicity - The stack should be available on every popular development platform and easy for someone to build for their platform of choice. It should be viable on CPU & memory limited devices.

Free & Open - Make the fundamental features free for all to use. Release all artifacts as open-source efforts with licensing that should facilitate and not impede adoption.

Interoperability & Reach - The wire-protocol must be capable of surviving traversal over common internet infrastructure.

General Purpose & Performant - The stack should be applicable to a broad class of use-cases while sacrificing little in performance when compared to a use-case specific stack.

Layered - Key facets of the stack must be able to evolve independently. A revision to the wire-format should not disrupt application layer bindings.

Payload Agnostic - Different services need to use different message types and encodings such as protocol buffers, JSON, XML, and Thrift; the protocol and implementations must allow for this. Similarly the need for payload compression varies by use-case and payload type: the protocol should allow for pluggable compression mechanisms.

Streaming - Storage systems rely on streaming and flow-control to express large data-sets. Other services, like voice-to-text or stock-tickers, rely on streaming to represent temporally related message sequences.

Blocking & Non-Blocking - Support both asynchronous and synchronous processing of the sequence of messages exchanged by a client and server. This is critical for scaling and handling streams on certain platforms.

Cancellation & Timeout - Operations can be expensive and long-lived - cancellation allows servers to reclaim resources when clients are well-behaved. When a causal-chain of work is tracked, cancellation can cascade. A client may indicate a timeout for a call, which allows services to tune their behavior to the needs of the client.

Lameducking - Servers must be allowed to gracefully shut-down by rejecting new requests while continuing to process in-flight ones.

Flow-Control - Computing power and network capacity are often unbalanced between client & server. Flow control allows for better buffer management as well as providing protection from DOS by an overly active peer.

Pluggable - A wire protocol is only part of a functioning API infrastructure. Large distributed systems need security, health-checking, load-balancing and failover, monitoring, tracing, logging, and so on. Implementations should provide extensions points to allow for plugging in these features and, where useful, default implementations.

Extensions as APIs - Extensions that require collaboration among services should favor using APIs rather than protocol extensions where possible. Extensions of this type could include health-checking, service introspection, load monitoring, and load-balancing assignment.

Metadata Exchange - Common cross-cutting concerns like authentication or tracing rely on the exchange of data that is not part of the declared interface of a service. Deployments rely on their ability to evolve these features at a different rate to the individual APIs exposed by services.

Standardized Status Codes - Clients typically respond to errors returned by API calls in a limited number of ways. The status code namespace should be constrained to make these error handling decisions clearer. If richer domain-specific status is needed the metadata exchange mechanism can be used to provide that.

Originally written by Louis Ryan with help from others at Google.

Saturday, February 27, 2016

Wordpress Troubleshoot: Error Updating Plugins After Upgrade My PHP Version to PHP7



Today, I really surprised that I can't update any plugins in my Wordpress website. All of function were working well but still can't update any plugins. I though only this one site was broken until I opened my other site and it was broken too!!! What happened!? That was like a nightmare :((
Then, I searched for the error log in the Wordpress admin directory and there were many errors occurred. Here are some of the error messages.

[25-Feb-2016 14:47:10 UTC] PHP Fatal error:  Uncaught Error: Function name must be a string in /wp-content/plugins/shareaholic/lib/social-share-counts/curl_multi_share_count.php:53
Stack trace:
#0 /wp-content/plugins/shareaholic/public.php(444): ShareaholicCurlMultiShareCount->get_counts()
#1 /wp-includes/plugin.php(525): ShareaholicPublic::share_counts_api('')
#2 /wp-admin/admin-ajax.php(89): do_action('wp_ajax_shareah...')
#3 {main}  thrown in /wp-content/plugins/shareaholic/lib/social-share-counts/curl_multi_share_count.php on line 53 
[25-Feb-2016 14:51:48 UTC] PHP Fatal error:  Uncaught Error: Function name must be a string in /wp-content/plugins/shareaholic/lib/social-share-counts/curl_multi_share_count.php:53
Stack trace:
#0 /wp-content/plugins/shareaholic/public.php(444): ShareaholicCurlMultiShareCount->get_counts()
#1 /wp-includes/plugin.php(525): ShareaholicPublic::share_counts_api('')
#2 /wp-admin/admin-ajax.php(99): do_action('wp_ajax_nopriv_...')
#3 {main}  thrown in /wp-content/plugins/shareaholic/lib/social-share-counts/curl_multi_share_count.php on line 53 
[26-Feb-2016 23:16:50 UTC] PHP Fatal error:  Uncaught Error: Call to undefined function ereg() in /wp-content/plugins/author-or-user-image/author_image.php:107
Stack trace:
#0 /wp-includes/plugin.php(525): zm_author_image->adinit('')
#1 /wp-admin/admin.php(168): do_action('admin_init')
#2 /wp-admin/update-core.php(10): require_once('/')
#3 {main}  thrown in /wp-content/plugins/author-or-user-image/author_image.php on line 107 
I googled for those error messages and found nothing related except an old post related to deprecated function ereg() in the older version of PHP. Aha! Maybe that is the source of the problems. I remembered that I changed the PHP version of my hosting from PHP 5.6 to PHP 7 about two days ago. My hosting provider said that by upgrading the PHP version to PHP 7 would improve the performance of Wordpress up to 130% of current performance. I totally sold to that advertisement at that time and changed my PHP version immediately.

I opened my cpanel and quickly downgraded my PHP version to 5.6.  Everything is working well now. I can update my plugins now. :) Lesson learned, don't too quick adopt the latest technology until it is stable enough and widely use.

Please leave a comment bellow if you find it useful.

Saturday, February 13, 2016

Dictionary: Philosophy Paper

Philosophy Paper contains a reasoned defense to a claim/thesis. Its objectives is to convince a reader about something that the writer want to say. From a philosophical writing, we can see someone's level of understanding of the subject problem or material because the writer can think critically about that that.

A philosophical paper may require several kinds of tasks, including:

  • Argument reconstruction 
  • Objections and replies 
  • Application 
  • Original argument 
  • Thought experiments

One good example of a philosophy paper is "Computing Machinery and Intelligence" by Alan M. Turing.

Source:

  • http://www.mit.edu/~yablo/writing.html
  • http://writingcenter.unc.edu/handouts/philosophy/
  • http://philosophy.fas.harvard.edu/files/phildept/files/brief_guide_to_writing_philosophy_paper.pdf
  • http://www.sfu.ca/philosophy/resources/writing.html

Wednesday, January 6, 2016

Git Tips: How to delete local branch and remote branch

I found this two commands very handy to keep your local and remote repositories clean from unused branches. Here are the steps that usually I use to keep my repositories clean:
  • First to check branches that exist in your local repository use the following command
$ git branch
  • After you see the list of your branches choose one you want to delete as seen bellow
$ git branch -d <your-branch-name>
  • To check branches that exist in your remote repository use this command
$ git branch -r
  •  And the to delete your remote branch use the following command
$ git push origin :<your-branch-name>
If you find this post useful, please leave a comment. :)

Tuesday, December 1, 2015

Laravel Troubleshoot: Get the composer install working

In my spare time, I started my new hobby project. And I chose Laravel framework for this project. After a few weeks working on this project, I changed my workspace and started with a new clone from my git repository. But when I tried to run :

$ php artisan serve

the code seemed not working. I got this kind of error:

require(../bootstrap/../vendor/autoload.php): failed to open stream: No such file or directory in .../bootstrap/autoload.php on line 17
PHP Fatal error:  require(): Failed opening required '/../vendor/autoload.php' (include_path='.:/usr/share/php:/usr/share/pear') in /../bootstrap/autoload.php on line 17

And I realized that I forgot to run:

$ composer install

a command to resolve all Laravel dependencies. But I got another error on that command :(

Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Installation request for laravel/framework v5.0.14 -> satisfiable by laravel/framework[v5.0.14].
    - laravel/framework v5.0.14 requires ext-mcrypt * -> the requested PHP extension mcrypt is missing from your system.

So, I did my search on this error and found out that I needed to install another PHP extension my crypt with these commands:

$ sudo apt-get install mcrypt
$ sudo apt-get install php5-mycrypt
$ sudo php5enmod mcrypt

After that I ran the composer install to resolve all the dependencies and php artisan serve seemed to be working again :)

Wednesday, May 6, 2015

ASP.NET Tips: Redirecting all uppercase letter in URL into lowercase URL

For the purpose of SEO, sometimes we need a way to enforce all URL into lowercase. In order to do that in an ASP.NET project, we can add a URL rewrite rules in the web config file inside the system.webserver tag.

Here is the configuration of URL rewrite looks like:

<system.webserver>
    <rewrite>
       <rules>
          <rule name="LowerCaseRuleRedirection" stopProcessing="true">
               <match url="[A-Z]" ignoreCase="false"/>
                <action type="Redirect" url="{ToLower:{URL}}" />
           </rule>
        </rules>
    </rewrite>
</system.webserver>

Please leave a comment if you find my post useful. Happy coding programmers! :)

Tuesday, January 6, 2015

CPNTools Troubleshoot: Beta execution aborted Reference is none.

Long time no see. Installing CPNTools for Windows is easy, but today I have a problem when installing cpntools on a Windows Server 2008. Actually the problem was not within the installation process but I can't run the CPNTools because there was an error that keep saying "CreateWindow failed. Error: 0. Create Child Window failed. Error 1406. # Beta execution aborted: Reference is none. # Error during dump: Access violation. Abortion." and creating a quite long dump file. 

I did searching for the error, and followed some guides like:
  • reinstalled the JDK/JRE.
  • made sure the system environment variable JAVA_HOME points to the installation location (e.g., c:\Program Files\Java\jre8)
  • made sure my PATH includes the bin directory under JAVA_HOME (in the example, it would have to include c:\Program Files\Java\jre8\bin).

But none of them worked. So I keep searching, but still no answer. And suddenly I remembered that there is a feature which is called Data Execution Prevention (DEP). DEP is a security feature that can help prevent damage to your computer from viruses, harmful programs, and other security threats. But sometimes DEP can also prevent your programs from being executed, and this also happened to my CPNTools. So to solve this I needed to add my cpntools.exe

You can solve it by following this step: 
Control Panel -> System and Security -> System -> Advanced System Settings.
It will open the System Properties Dialog and move to the Advanced tab and click the "Settings" button. Another dialog will be opened, and you need to go to "Data Execution Prevention" tab and add the cpntools.exe to the whitelist. And now my CPNTools works nicely. :D

======================================================
Bellow is the complete content of my cpntools.dump:

Beta execution aborted: Reference is none.

Call chain: (nti_ms)

  item <handleframeChanged#> in ~beta/guienv/private/winnt/guienv_ntiprivate
    -- windowContents#canvas#windowitem#interfaceObject# in ~beta/guienv/private/winnt/guienv_ntiprivate
  item <*> in ~beta/guienv/private/winnt/guienv_ntibody
    -- * in ~beta/guienv/guienv
  item <*> in ~beta/guienv/guienv
    -- frame# in ~beta/guienv/guienv
  item <frame#> in ~beta/guienv/guienv
    -- windowContents#canvas#windowitem#interfaceObject# in ~beta/guienv/private/winnt/guienv_ntiprivate
  item <*> in ~beta/guienv/guienv
    -- size# in ~beta/guienv/guienv
  item <size#> in ~beta/guienv/guienv
    -- windowContents#canvas#windowitem#interfaceObject# in ~beta/guienv/private/winnt/guienv_ntiprivate
  item <create#>create# in ~beta/guienv/guienv
    -- open#open#open# in ~beta/postwimp/foundation/guisurface
  item create#<create#> in ~beta/guienv/guienv
    -- open#open#open# in ~beta/postwimp/foundation/guisurface
  item <*> in ~beta/guienv/private/winnt/guienv_ntibody
    -- open#open#open# in ~beta/postwimp/foundation/guisurface
  item open#open#<open#> in ~beta/guienv/guienv
    -- main#window#interfaceObject# in ~beta/postwimp/foundation/guisurface
  item <init#>init# in ~beta/postwimp/foundation/guisurface
    -- GUISurface#Surface# in ~beta/postwimp/foundation/guisurface
  item init#<init#> in ~beta/postwimp/foundation/abstractsurface
    -- GUISurface#Surface# in ~beta/postwimp/foundation/guisurface
  item <*> in ~beta/postwimp/foundation/private/worldbody_nti
    -- * in ~beta/postwimp/foundation/private/worldbody_nti
  item <*> in ~beta/postwimp/foundation/private/worldbody_nti
    -- platformSetWindowEnv# in ~beta/postwimp/foundation/private/worldbody
  item <platformSetWindowEnv#> in ~beta/postwimp/foundation/private/worldbody
    -- PROGRAM-~CPNWorkSpace#Workspace#World#SystemEnv#SysHead# in C:/cpn2000/cpntools/cpntools
  item <setWindowEnv#> in ~beta/postwimp/foundation/world
    -- PROGRAM-~CPNWorkSpace#Workspace#World#SystemEnv#SysHead# in C:/cpn2000/cpntools/cpntools
  item <start#> in ~beta/guienv/private/winnt/guienvntsystemenvbody
    -- PIOPRIVATE-~ in ~beta/guienv/private/winnt/guienvntsystemenvbody
  comp <BASICSCHEDULER-~>SysHead# in ~beta/guienv/private/winnt/guienvntsystemenvbody
    -- PROGRAM-~CPNWorkSpace#Workspace#World#SystemEnv#SysHead# in C:/cpn2000/cpntools/cpntools
  comp BASICSCHEDULER-~<SysHead#> in ~beta/basiclib/basicsystemenv
    -- BETAENV-~ in ~beta/basiclib/betaenv

  item <*> in ~beta/basiclib/betaenv
    -- BETAENV-~ in ~beta/basiclib/betaenv
  basic component in ~beta/basiclib/betaenv


Low level information:

Call chain: (nti_ms)

  item <handleframeChanged#> in ~beta/guienv/private/winnt/guienv_ntiprivate
  { PC  0x49cb97Warning! nm(DumpSectionTable): Couldn't find section number of .text
 < +0x2ecb96>, object 0x2977938, proto 0x9ae2e2 handleframeChanged# [ast: 0x0008,0x0003] < +0x7fe2e1> }
    -- windowContents#canvas#windowitem#interfaceObject# in ~beta/guienv/private/winnt/guienv_ntiprivate
    { Surrounding object 0x2974020, proto 0x9afe0a windowContents# [ast: 0x0007,0x003f] < +0x7ffe09> }
  item <handleframeChanged#> in ~beta/guienv/private/winnt/guienv_ntiprivate
  { PC  0x49cb97 < +0x2ecb96>, object 0x2977938, proto 0x9ae2e2 handleframeChanged# [ast: 0x0008,0x0003] < +0x7fe2e1> }
    -- windowContents#canvas#windowitem#interfaceObject# in ~beta/guienv/private/winnt/guienv_ntiprivate
    { Surrounding object 0x2974020, proto 0x9afe0a windowContents# [ast: 0x0007,0x003f] < +0x7ffe09> }
  item <handleframeChanged#> in ~beta/guienv/private/winnt/guienv_ntiprivate
  { PC  0x49cb97 < +0x2ecb96>, object 0x2977938, proto 0x9ae2e2 handleframeChanged# [ast: 0x0008,0x0003] < +0x7fe2e1> }
    -- windowContents#canvas#windowitem#interfaceObject# in ~beta/guienv/private/winnt/guienv_ntiprivate
    { Surrounding object 0x2974020, proto 0x9afe0a windowContents# [ast: 0x0007,0x003f] < +0x7ffe09> }
  item <handleframeChanged#> in ~beta/guienv/private/winnt/guienv_ntiprivate
  { PC  0x49cb97 < +0x2ecb96>, object 0x2977938, proto 0x9ae2e2 handleframeChanged# [ast: 0x0008,0x0003] < +0x7fe2e1> }
    -- windowContents#canvas#windowitem#interfaceObject# in ~beta/guienv/private/winnt/guienv_ntiprivate
    { Surrounding object 0x2974020, proto 0x9afe0a windowContents# [ast: 0x0007,0x003f] < +0x7ffe09> }
  item <handleframeChanged#> in ~beta/guienv/private/winnt/guienv_ntiprivate
  { PC  0x49cb97 < +0x2ecb96>, object 0x2977938, proto 0x9ae2e2 handleframeChanged# [ast: 0x0008,0x0003] < +0x7fe2e1> }
    -- windowContents#canvas#windowitem#interfaceObject# in ~beta/guienv/private/winnt/guienv_ntiprivate
    { Surrounding object 0x2974020, proto 0x9afe0a windowContents# [ast: 0x0007,0x003f] < +0x7ffe09> }
  item <handleframeChanged#> in ~beta/guienv/private/winnt/guienv_ntiprivate
  { PC  0x49cb97 < +0x2ecb96>, object 0x2977938, proto 0x9ae2e2 handleframeChanged# [ast: 0x0008,0x0003] < +0x7fe2e1> }
    -- windowContents#canvas#windowitem#interfaceObject# in ~beta/guienv/private/winnt/guienv_ntiprivate
    { Surrounding object 0x2974020, proto 0x9afe0a windowContents# [ast: 0x0007,0x003f] < +0x7ffe09> }
  item <handleframeChanged#> in ~beta/guienv/private/winnt/guienv_ntiprivate
  { PC  0x49cb97 < +0x2ecb96>, object 0x2977938, proto 0x9ae2e2 handleframeChanged# [ast: 0x0008,0x0003] < +0x7fe2e1> }
    -- windowContents#canvas#windowitem#interfaceObject# in ~beta/guienv/private/winnt/guienv_ntiprivate
    { Surrounding object 0x2974020, proto 0x9afe0a windowContents# [ast: 0x0007,0x003f] < +0x7ffe09> }
  item <handleframeChanged#> in ~beta/guienv/private/winnt/guienv_ntiprivate
  { PC  0x49cb97 < +0x2ecb96>, object 0x2977938, proto 0x9ae2e2 handleframeChanged# [ast: 0x0008,0x0003] < +0x7fe2e1> }
    -- windowContents#canvas#windowitem#interfaceObject# in ~beta/guienv/private/winnt/guienv_ntiprivate
    { Surrounding object 0x2974020, proto 0x9afe0a windowContents# [ast: 0x0007,0x003f] < +0x7ffe09> }
  item <handleframeChanged#> in ~beta/guienv/private/winnt/guienv_ntiprivate
  { PC  0x49cb97 < +0x2ecb96>, object 0x2977938, proto 0x9ae2e2 handleframeChanged# [ast: 0x0008,0x0003] < +0x7fe2e1> }
    -- windowContents#canvas#windowitem#interfaceObject# in ~beta/guienv/private/winnt/guienv_ntiprivate
    { Surrounding object 0x2974020, proto 0x9afe0a windowContents# [ast: 0x0007,0x003f] < +0x7ffe09> }
  item <handleframeChanged#> in ~beta/guienv/private/winnt/guienv_ntiprivate
  { PC  0x49cb97 < +0x2ecb96>, object 0x2977938, proto 0x9ae2e2 handleframeChanged# [ast: 0x0008,0x0003] < +0x7fe2e1> }
    -- windowContents#canvas#windowitem#interfaceObject# in ~beta/guienv/private/winnt/guienv_ntiprivate
    { Surrounding object 0x2974020, proto 0x9afe0a windowContents# [ast: 0x0007,0x003f] < +0x7ffe09> }
  item <handleframeChanged#> in ~beta/guienv/private/winnt/guienv_ntiprivate
  { PC  0x49cb97 < +0x2ecb96>, object 0x2977938, proto 0x9ae2e2 handleframeChanged# [ast: 0x0008,0x0003] < +0x7fe2e1> }
    -- windowContents#canvas#windowitem#interfaceObject# in ~beta/guienv/private/winnt/guienv_ntiprivate
    { Surrounding object 0x2974020, proto 0x9afe0a windowContents# [ast: 0x0007,0x003f] < +0x7ffe09> }
  item <handleframeChanged#> in ~beta/guienv/private/winnt/guienv_ntiprivate
  { PC  0x49cb97 < +0x2ecb96>, object 0x2977938, proto 0x9ae2e2 handleframeChanged# [ast: 0x0008,0x0003] < +0x7fe2e1> }
    -- windowContents#canvas#windowitem#interfaceObject# in ~beta/guienv/private/winnt/guienv_ntiprivate
    { Surrounding object 0x2974020, proto 0x9afe0a windowContents# [ast: 0x0007,0x003f] < +0x7ffe09> }
  item <*> in ~beta/guienv/private/winnt/guienv_ntibody
  { PC  0x4a0d9b < +0x2f0d9a>, object 0x29777b8, proto 0x9a8262 * [ast: 0x0069,0x0002] < +0x7f8261> }
    -- * in ~beta/guienv/guienv
    { Surrounding object 0x2977748, proto 0x9bad8e * [ast: 0x0001,0x071f] < +0x80ad8d> }
  item <*> in ~beta/guienv/guienv
  { PC  0x4a091f < +0x2f091e>, object 0x2977748, proto 0x9bad8e * [ast: 0x0001,0x071f] < +0x80ad8d> }
    -- frame# in ~beta/guienv/guienv
    { Surrounding object 0x2977718, proto 0x9bad56 frame# [ast: 0x0001,0x0717] < +0x80ad55> }
  item <frame#> in ~beta/guienv/guienv
  { PC  0x4a1425 < +0x2f1424>, object 0x2977718, proto 0x9bad56 frame# [ast: 0x0001,0x0717] < +0x80ad55> }
    -- windowContents#canvas#windowitem#interfaceObject# in ~beta/guienv/private/winnt/guienv_ntiprivate
    { Surrounding object 0x2974020, proto 0x9afe0a windowContents# [ast: 0x0007,0x003f] < +0x7ffe09> }
  item <*> in ~beta/guienv/guienv
  { PC  0x4a1235 < +0x2f1234>, object 0x2977628, proto 0x9baecc * [ast: 0x0001,0x075f] < +0x80aecb> }
    -- size# in ~beta/guienv/guienv
    { Surrounding object 0x29775f0, proto 0x9bae9e size# [ast: 0x0001,0x0757] < +0x80ae9d> }
  item <size#> in ~beta/guienv/guienv
  { PC  0x444681 < +0x294680>, object 0x29775f0, proto 0x9bae9e size# [ast: 0x0001,0x0757] < +0x80ae9d> }
    -- windowContents#canvas#windowitem#interfaceObject# in ~beta/guienv/private/winnt/guienv_ntiprivate
    { Surrounding object 0x2974020, proto 0x9afe0a windowContents# [ast: 0x0007,0x003f] < +0x7ffe09> }
  item <create#>create# in ~beta/guienv/guienv
  { PC  0x443ab3 < +0x293ab2>, object 0x2976558, proto 0x9bbeea create# [ast: 0x0001,0x0a0d] < +0x80bee9> }
    -- open#open#open# in ~beta/postwimp/foundation/guisurface
    { Surrounding object 0x2976518, proto 0x9a40f2 open# [ast: 0x0001,0x08ae] < +0x7f40f1> }
  item create#<create#> in ~beta/guienv/guienv
  { PC  0x49864a < +0x2e8649>, object 0x2976558, proto 0x9b8f46 create# [ast: 0x0001,0x01a5] < +0x808f45> }
    -- open#open#open# in ~beta/postwimp/foundation/guisurface
    { Surrounding object 0x2976518, proto 0x9a40f2 open# [ast: 0x0001,0x08ae] < +0x7f40f1> }
  item <*> in ~beta/guienv/private/winnt/guienv_ntibody
  { PC  0x4986ce < +0x2e86cd>, object 0x2976548, proto 0x9a6e34 * [ast: 0x0021,0x0002] < +0x7f6e33> }
    -- open#open#open# in ~beta/postwimp/foundation/guisurface
    { Surrounding object 0x2976518, proto 0x9a40f2 open# [ast: 0x0001,0x08ae] < +0x7f40f1> }
  item open#open#<open#> in ~beta/guienv/guienv
  { PC  0x498676 < +0x2e8675>, object 0x2976518, proto 0x9b8f14 open# [ast: 0x0001,0x01a1] < +0x808f13> }
    -- main#window#interfaceObject# in ~beta/postwimp/foundation/guisurface
    { Surrounding object 0x29735c8, proto 0x9a4090 main# [ast: 0x0001,0x08a8] < +0x7f408f> }
  item <init#>init# in ~beta/postwimp/foundation/guisurface
  { PC  0x48ed08 < +0x2ded07>, object 0x2976458, proto 0x9a46a8 init# [ast: 0x0001,0x0b59] < +0x7f46a7> }
    -- GUISurface#Surface# in ~beta/postwimp/foundation/guisurface
    { Surrounding object 0x2973258, proto 0x9a3236 GUISurface# [ast: 0x0001,0x0048] < +0x7f3235> }
  item init#<init#> in ~beta/postwimp/foundation/abstractsurface
  { PC  0x739047 < +0x589046>, object 0x2976458, proto 0xad4702 init# [ast: 0x0001,0x0b45] < +0x924701> }
    -- GUISurface#Surface# in ~beta/postwimp/foundation/guisurface
    { Surrounding object 0x2973258, proto 0x9a3236 GUISurface# [ast: 0x0001,0x0048] < +0x7f3235> }
  item <*> in ~beta/postwimp/foundation/private/worldbody_nti
  { PC  0x48d8a3 < +0x2dd8a2>, object 0x2973248, proto 0x9a2cec * [ast: 0x0008,0x0039] < +0x7f2ceb> }
    -- * in ~beta/postwimp/foundation/private/worldbody_nti
    { Surrounding object 0x2972f38, proto 0x9a2cc0 * [ast: 0x0008,0x0002] < +0x7f2cbf> }
  item <*> in ~beta/postwimp/foundation/private/worldbody_nti
  { PC  0x48d792 < +0x2dd791>, object 0x2972f38, proto 0x9a2cc0 * [ast: 0x0008,0x0002] < +0x7f2cbf> }
    -- platformSetWindowEnv# in ~beta/postwimp/foundation/private/worldbody
    { Surrounding object 0x2972f08, proto 0xa11aaa platformSetWindowEnv# [ast: 0x0003,0x0003] < +0x861aa9> }
  item <platformSetWindowEnv#> in ~beta/postwimp/foundation/private/worldbody
  { PC  0x48d627 < +0x2dd626>, object 0x2972f08, proto 0xa11aaa platformSetWindowEnv# [ast: 0x0003,0x0003] < +0x861aa9> }
    -- PROGRAM-~CPNWorkSpace#Workspace#World#SystemEnv#SysHead# in C:/cpn2000/cpntools/cpntools
    { Surrounding object 0x2970c10, proto 0xa0e0a0 PROGRAM-~ [ast: 0x0001,0x0001] < +0x85e09f> }
  item <setWindowEnv#> in ~beta/postwimp/foundation/world
  { PC  0x631d6b < +0x481d6a>, object 0x2972ef8, proto 0xacf3ac setWindowEnv# [ast: 0x0001,0x1da3] < +0x91f3ab> }
    -- PROGRAM-~CPNWorkSpace#Workspace#World#SystemEnv#SysHead# in C:/cpn2000/cpntools/cpntools
    { Surrounding object 0x2970c10, proto 0xa0e0a0 PROGRAM-~ [ast: 0x0001,0x0001] < +0x85e09f> }
  item <start#> in ~beta/guienv/private/winnt/guienvntsystemenvbody
  { PC  0x44c4b7 < +0x29c4b6>, object 0x2972ee8, proto 0x96ddc4 start# [ast: 0x0005,0x01aa] < +0x7bddc3> }
    -- PIOPRIVATE-~ in ~beta/guienv/private/winnt/guienvntsystemenvbody
    { Surrounding object 0x2971f30, proto 0x96db8e PIOPRIVATE-~ [ast: 0x0005,0x0001] < +0x7bdb8d> }
  comp <BASICSCHEDULER-~>SysHead# in ~beta/guienv/private/winnt/guienvntsystemenvbody
  { PC  0x44ba90 < +0x29ba8f>, object 0x2972dc0, proto 0x96dade BASICSCHEDULER-~ [ast: 0x0002,0x0001] < +0x7bdadd> }
    -- PROGRAM-~CPNWorkSpace#Workspace#World#SystemEnv#SysHead# in C:/cpn2000/cpntools/cpntools
    { Surrounding object 0x2970c10, proto 0xa0e0a0 PROGRAM-~ [ast: 0x0001,0x0001] < +0x85e09f> }
  comp BASICSCHEDULER-~<SysHead#> in ~beta/basiclib/basicsystemenv
  { PC  0x740b4b < +0x590b4a>, object 0x2972dc0, proto 0xadb516 SysHead# [ast: 0x0001,0x0310] < +0x92b515> }
    -- BETAENV-~ in ~beta/basiclib/betaenv
    { Surrounding object 0x2970060, proto 0x94e3a0 BETAENV-~ [ast: 0x0001,0x0001] < +0x79e39f> }

  item <*> in ~beta/basiclib/betaenv
  { PC  0x48b24c < +0x2db24b>, object 0x2970b48, proto 0x9509aa * [ast: 0x0001,0x0c3c] < +0x7a09a9> }
    -- BETAENV-~ in ~beta/basiclib/betaenv
    { Surrounding object 0x2970060, proto 0x94e3a0 BETAENV-~ [ast: 0x0001,0x0001] < +0x79e39f> }
  basic component in ~beta/basiclib/betaenv

Legend:

The above dumps show the dynamic call stack of invoked objects.
Each dump starts at the object that was the current object when
the error occurred and continues down towards the basic component.
The descriptions have the following meaning:
1. Items are shown in two lines, like this:
      item <name#>pname1#pname2#pname3 in ifile
        -- sname#spname1#spname2 in sfile
   meaning that the item is an instance of the pattern "name" which
   has prefix "pname1" which has prefix "pname2", etc.
   This item is defined in the file "ifile".
   The part of the prefix chain enclosed in "<" and ">" indicates
   where in the action sequence the error occurred.
   The line beginning with "--" shows the textually surrounding
   pattern using the same notation.
2. The descriptor names used in the above description will normally
   have one or more "meta characters" appended. These mean:
      #  The descriptor belongs to a pattern, e.g. P: (# ... #)
      ~  Singular named descriptor, e.g. X: @(# ... #)
      *  Singular unnamed descriptor, e.g. ... ; (# ... #) ; ...
      -  Descriptor SLOT.
3. Components are shown using a notation similar to that of items:
      comp <name#>pname1#pname2#pname3 in cfile
4. The bottommost component corresponding to the basic environment is
   shown like an ordinary component, but indicated with
      basic component <name#>pname1#pname2#pname3 in cfile
5. In case the error occurred in some external code called from BETA,
   the top of the call stack is shown as
      [ EXTERNAL ACTIVATION PART ]
6. In case the BETA code has called some external code which has in
   turn called back into the BETA code, and the callback is still
   active at the point of the error, the intermediate call stack part
   is shown as
      [ EXTERNAL ACTIVATION PART ]
7. The section labeled "Low level information" can be avoided by
      set BETART=SimpleDump
   before subsequent executions of the program.

Finally, C# 9 record, the equivalent of Scala's case class

While C# is a wonderful programming language, there is something that I would like to see to make our life programmer easier. If you are fam...