blog.ramp51.com Open in urlscan Pro
18.209.39.3  Public Scan

Submitted URL: http://blog.ramp51.com/
Effective URL: https://blog.ramp51.com/
Submission: On December 01 via api from FI — Scanned from FI

Form analysis 2 forms found in the DOM

GET https://blog.ramp51.com/

<form role="search" aria-label="Search for:" method="get" class="search-form" action="https://blog.ramp51.com/">
  <label for="search-form-1">
    <span class="screen-reader-text"> Search for: </span>
    <input type="search" id="search-form-1" class="search-field" placeholder="Search …" value="" name="s">
  </label>
  <input type="submit" class="search-submit" value="Search">
</form>

GET https://blog.ramp51.com/

<form role="search" method="get" class="search-form" action="https://blog.ramp51.com/">
  <label for="search-form-2">
    <span class="screen-reader-text"> Search for: </span>
    <input type="search" id="search-form-2" class="search-field" placeholder="Search …" value="" name="s">
  </label>
  <input type="submit" class="search-submit" value="Search">
</form>

Text Content

Skip to the content
Search


RAMP51 TECHNOLOGY BLOG

Learning, Discovering, and Sharing ideas.
Menu
Search
Search for:
Close search
Close Menu


Categories
Software Development


THE HOVERING LAPTOP

 * Post author By Mark Squires
 * Post date August 12, 2022
 * No Comments on The hovering laptop

The hovering laptop


“I NEED MY LAPTOP TO HOVER IN THE AIR. WHO CAN BUILD THIS, OR CAN YOU RECOMMEND
SOMEONE THAT IS SELLING THIS FEATURE?”

So, you work in technology, in some role trying to deliver solutions to
stakeholders. When you receive the request “I need my laptop to hover in the
air,” what do you do next?

It’s natural to want to be the first one to display your technical prowess
balanced by your profound sense of how to deliver ROI (a problem I clearly
struggle with, lol); listing the reasons why you can’t solve this, that the
existing tooling won’t support it, or that the risk/reward is just too
unbalanced to even try.

After your response, the requestor assumes it can’t be done or isn’t worth
doing, and everyone moves on. Do we really know what we left to die on the
table?

The example of a hovering laptop is absurd enough that most of us probably
think, “I would definitely ask WHY before responding?” While that may be true,
we often get requests where our assumptions about the request defeat our best
intention of asking WHY?

More than ever, the stakeholders we work with tend to come to us with solutions
rather than problems and are more technically inclined than their counterparts
from 20 years ago. Naturally as people become more tech savvy and more aware of
the techniques used to deliver solutions they become more solution focused.

We need to ask questions we didn’t have to ask 20 years ago. When people were
more likely to come to you and say, “I’m not a techie! Here is what I do today;
my boss told me to loop your team in to see how we can improve the process.” At
this point, you’d start learning about the process they want to be improved,
what data is involved, how frequently it changes, and the people involved, along
with other factors, and formulate a proposed new process.

Today many stakeholders are “Solution Proposers” and technologists as “Solution
Providers” we need to be experts at peeling back the layers of the proposed
solution to identify how and why the requestor came to the conclusion that they
need “A hovering laptop.” Maybe they are right, maybe they do need a hovering
laptop.

Despite whether they are right or wrong, as a solution provider, I still want to
ensure that any solution I put in place will address the underlying needs
driving the request. So we start asking questions.

 * While your laptop is hovering, will you be actively using it? Is it a touch
   screen, will you use an attached mouse and keyboard, or the keyboard and
   touchpad that are built in?
 * Are you mobile while using this hovering laptop? Are you sitting, standing,
   or riding something?

Your approach may vary depending on the people you are working with. For some,
asking questions about the solution requested can be a more straightforward
approach aligned with how the stakeholder already views the outcome. Remind them
that you just want to talk through the proposed solution and that you are there
not just to deliver a solution but to help them make an appropriate decision on
what solution best meets all of the goals and constraints they may not have
shared yet.

From your initial questions the requestor may start simplifying their request:

> Hrm. I guess if I’m just sitting at my desk, I could use something to lift the
> laptop up. It doesn’t really need to hover, per se.

Maybe the requestor has never seen a riser that sits on a desk, or perhaps the
requestor is just assuming the company wouldn’t build a shelf above her desk or
that the cubicle wall won’t support attaching a shelf.

Clearly, today, if we really wanted, we could make a laptop hover. It would
likely come with a lot of unintended user experience problems.

We can probably find a simpler, cheaper, faster to deploy, and less likely to
fail solution. We just need to get to the WHY. We can only do that through
curiosity and understanding of what brought the requestor to suggest the
specific solution they did.

This post is getting pretty long, so I’ll just end it by saying: Don’t lead the
conversation by enumerating the reasons you can’t deliver what is being asked.
First seek to understand why you are being asked for a particular solutions.



--------------------------------------------------------------------------------

Categories
Software Development Visual Basic.NET


IS IIF PART OF THE VB.NET LANGUAGE?

 * Post author By Mark Squires
 * Post date April 14, 2022
 * No Comments on Is IIF part of the VB.NET language?



The answer is NO. Does it feel like it is part of the language, YES.

When coding in Visual Basic.NET you’ll come across three variations of an “IF”.

 * IIF Function
 * IF() Operator
 * IF…Then…Else Statement

The IF() operator and the IF…Then…Else Statement are part of the VB.NET
Language.

The IIF Function is not, even though you can use it. These three features
operate differently and have different purposes, this post isn’t meant to get
into those differences, but will discuss how IIF() and IF() are defined and used
by the compiler. Most likely when you are using the IIF Function, you probably
want to be using the IF() Operator.

The IIF function is imported by default due to the VB Compiler Response file
that is included when the compiler is installed. The VB Compiler Response file
includes a line which makes this possible:

/imports:Microsoft.VisualBasic

The Microsoft.VisualBasic.dll is always referenced by the compiler regardless of
what command line options you specify.

Which is why compiling this code will work, even though IIF is NOT part of the
Visual Basic .NET language.

Module Module1

    Sub Main()

        Console.WriteLine(IIf(True, "Hi Mark", "Hi Tom"))


    End Sub

End Module

Which is successfully compiled with this command

vbc ExampleModule.vb

However, if you were to enter this command

vbc /noconfig ExampleModule.vb

You would be presented with the following errors:

error BC30451: 'Console' is not declared. It may be inaccessible due to its protection level.

        Console.WriteLine(IIf(True, "Hi Mark", "Hi Tom"))
        ~~~~~~~

error BC30451: 'IIf' is not declared. It may be inaccessible due to its protection level.

        Console.WriteLine(IIf(True, "Hi Mark", "Hi Tom"))
                          ~~~

There are two errors, because /noconfig caused the vb compiler to not load the
compiler responses file, which means neither System or Microsoft.VisualBasic
were imported by default.

If we modify our code above, to include these imports, it will now compile with
/noconfig

Imports System
Imports Microsoft.VisualBasic

Module Module1
    Sub Main()
        Console.WriteLine(IIf(True, "Hi Mark", "Hi Tom"))
    End Sub
End Module

This will compile with the /noconfig flag. Since there isn’t any reason to make
our lives harder we typically wouldn’t run VBC with the /noconfig (although
Visual Studio does, but at least there it deals with specificying all the
required parameters.)


IF IIF ISN’T PART OF THE LANGUAGE WHERE DOES IT COME FROM?

Inside the Microsoft.VisualBasic.dll there is a Module named Interactions which
defines the globally scoped function IIF

public static object IIf (bool Expression, object TruePart, object FalsePart);

Due to Microsoft.VisualBasic.dll being referenced by the compiler intrinsically
and the Import of the Microsoft.VisualBasic namespace by the compiler responses
file (in the case of a Visual Studio project it’s specified in the build file,)
the IIF function is available for use automatically.


WHY IS THE IIF FUNCTION THERE WHEN WE HAVE THE IF() OPERATOR?

I don’t have a first hand answer from any decision makers involved in drafting
the Visual Basic Language specification, so this answer is part research,
intuition, and speculation.

From 2002 to 2008, the Visual Basic.NET language didn’t offer the IF() Operator.
Prior to Visual Basic.NET, Basic and Visual Basic programmers had access to an
IIF function in many other languages, like VBA, FoxPro, and T-SQL. I believe I
remember using it in versions of Basic and Visual Basic, but can’t find any
supporting documentation.

In addition to retaining the functionality programmers were used to; adding it
to Visual Basic.NET with similar behavior to what existed prior likely made
upgrading old basic systems to VB.NET an easier process.

In 2008, with Visual Basic .NET 9.0 the IF() operator was introduced. Also
bringing forward the wave of new advice and discussions of using “IF() instead
of IIF()”


IF IIF IS NOT PART OF THE LANGUAGE, THEN WHAT IS IT?

Ok, so strictly speaking, it’s not a feature of the Visual Basic.NET language.
On the other hand if you create a Code.vb txt file and compile it, by default
IIF is a feature available to you. Which is also true when creating a new
project in Visual Studio. I’d call it a Framework feature that is available to
VB code files by default.


IF IIF IS A FRAMEWORK FEATURE, CAN WE USE IT FROM C#?

Let’s give it a try, we’ll start with this code

namespace ExampleIfInCSharp
{
    using System;
    using Microsoft.VisualBasic;

    public class Program
    {
        public static int Main(string[] args)
        {
            // Framework Feature IIF, in Microsoft.VisualBasic
            Console.WriteLine(IIF(true, "Hi Mark", "Hi Tom"));
            Console.WriteLine(IIF(false, "Hi Mark", "Hi Tom"));

            // C# Language Feature - Ternary Operator
            Console.WriteLine(true ? "Hi Mark" : "Hi Tom");

            // VB.NET Language Feature - IF() Operator
            //    this won't compile with C# 
            Console.WriteLine(IF(true, "Hi Mark", "Hi Tom"));

            return 0;
        }
    }
}

Now let’s try to compile that

csc iif-in-csharp.cs
Microsoft (R) Visual C# Compiler version 3.10.0-4.21318.11 (7ceb6331)
Copyright (C) Microsoft Corporation. All rights reserved.

iif-in-csharp.cs(11,31): error CS0103: The name 'IIF' does not exist in the current context
iif-in-csharp.cs(12,31): error CS0103: The name 'IIF' does not exist in the current context
iif-in-csharp.cs(19,31): error CS0103: The name 'IF' does not exist in the current context

We see that the compile does not like IF or IIF. Above we discovered that IIF
requires a reference to the Microsoft.VisualBasic.dll which happens
automatically with the VB Compiler, and that the VB Compiler Responses file
automatically Imports the Microsoft.VisualBasic namespace.

Let’s take this a step further, our code already has a using importing the
Microsoft.VisualBasic namespace. Let’s add a reference to
Microsoft.VisualBasic.dll and compile:

csc /r:Microsoft.VisualBasic.dll iif-in-csharp.cs
Microsoft (R) Visual C# Compiler version 3.10.0-4.21318.11 (7ceb6331)
Copyright (C) Microsoft Corporation. All rights reserved.

iif-in-csharp.cs(11,31): error CS0103: The name 'IIF' does not exist in the current context
iif-in-csharp.cs(12,31): error CS0103: The name 'IIF' does not exist in the current context
iif-in-csharp.cs(19,31): error CS0103: The name 'IF' does not exist in the current context

What is interesting here, is that we now have a reference to
Microsoft.VisualBasic.dll and a using for Microsoft.VisualBasic in our code. The
code hasn’t changed from above, all we changed was command we were using to
compile our code. We still have all of the same errors though.

C# is different from VB.NET; it has different language features. A feature of C#
is that it’s case sensitive, while VB.NET is case-insensitive. Also VB.NET
supports global modules as a feature while C# does not support modules. I think
we have to make a few more code changes:

We are going to change the casing of IIF to IIf, and prefix it with the module
name Interaction.

namespace ExampleIfInCSharp
{
    using System;
    using Microsoft.VisualBasic;

    public class Program
    {
        public static int Main(string[] args)
        {
            // Framework Feature IIF, in Microsoft.VisualBasic
            Console.WriteLine(Interaction.IIf(true, "Hi Mark", "Hi Tom"));
            Console.WriteLine(Interaction.IIf(false, "Hi Mark", "Hi Tom"));

            // C# Language Feature - Ternary Operator
            Console.WriteLine(true ? "Hi Mark" : "Hi Tom");

            // VB.NET Language Feature - IF() Operator
            //    this won't compile with C# 
            Console.WriteLine(IF(true, "Hi Mark", "Hi Tom"));

            return 0;
        }
    }
}

Now we’ll compile this and see what happens:

csc /r:Microsoft.VisualBasic.dll iif-in-csharp.cs
Microsoft (R) Visual C# Compiler version 3.10.0-4.21318.11 (7ceb6331)
Copyright (C) Microsoft Corporation. All rights reserved.

iif-in-csharp.cs(19,31): error CS0103: The name 'IF' does not exist in the current context

Progress! We have IIf working in our c# code, but we still have the problem with
the IF() operator. Our only choice is to remove this from our code, or create
our own function named If(), but we would never do this, because the C# ternary
operator (?:) does the same thing, and adding an If() function would create
confusion. Additionally writing an IF() function in C# would still not behave
like the IF() operator in VB, it would behave just like the IIF function.

The IF() operator can not be used directly in C# because of where it’s defined.
It’s a language feature, meaning it’s specified in the “grammar” of what makes a
Visual Basic.NET program. There isn’t a way to tell the CSharp compiler that it
should refer to the Visual Basic.NET Grammar, which makes a lot of sense. This
would be like trying to convince your swim teacher that a basketball is required
for swimming. Clearly a basketball is not a tool in a swimmer’s toolbox. Just as
the CSC compiler wouldn’t consider IF() as tool that could be used by a
programmer in a C# program.

The IIF function is available to C# and VB.NET because it’s part of the
“Framework.” It was coded in some language, which is irrelevant, and it was
compiled into a .NET assembly, therefore .NET Applications can reference that
assembly and use the publicly exposed types in it.

Here is our final program in C#

namespace ExampleIfInCSharp
{
    using System;
    using Microsoft.VisualBasic;

    public class Program
    {
        public static int Main(string[] args)
        {
            // Framework Feature IIF, in Microsoft.VisualBasic
            Console.WriteLine(Interaction.IIf(true, "Hi Mark", "Hi Tom"));
            Console.WriteLine(Interaction.IIf(false, "Hi Mark", "Hi Tom"));

            // C# Language Feature - Ternary Operator
            Console.WriteLine(true ? "Hi Mark" : "Hi Tom");

            // VB.NET Language Feature - IF() Operator
            //    this won't compile with C# 
            //Console.WriteLine(IF(true, "Hi Mark", "Hi Tom"));

            return 0;
        }
    }
}

And when we compile, Voila! No errors.

csc /r:Microsoft.VisualBasic.dll iif-in-csharp.cs
Microsoft (R) Visual C# Compiler version 3.10.0-4.21318.11 (7ceb6331)
Copyright (C) Microsoft Corporation. All rights reserved.

In conclusion, we can use framework features in any language, although you can
see in this case how Microsoft made it difficult to use this in C# but not
impossible. This is probably intentional since using IIf in C# wouldn’t add any
value to a C# program. Today most would argue that IIf doesn’t add any value to
a VB.NET program either, unless you had a very specific need for a confusing
line of code that represented logic branching in an IF-like structure but didn’t
have short-circuiting.



--------------------------------------------------------------------------------

Categories
C# Style Best Practice Software Development


METHOD DESIGN – EXCEPTIONAL BEHAVIORS

 * Post author By Mark Squires
 * Post date March 18, 2022
 * No Comments on Method Design – Exceptional Behaviors

Method Design - Exceptional Behaviors

When designing methods in our solutions, it’s hard to communicate all of the
behaviors of the method we are writing. How does the caller of our method know
what the behaviors of the method will be?

 * Will it throw exceptions?
 * Will it block?
 * Will it cause side effects?
 * Will it retry?
 * Will it be idempotent?



My team and I try to adhere to a default set of behavioral assumptions about
methods. Let’s also keep in mind that there are at least two contexts under
which a method is designed. The first group being methods only intended to be
used by their creators (usually private or internal), but of course if you work
on a team of developers you won’t be the only one using the methods you write.
The other context is a method which we expect others to use and maybe even
developers that we don’t know or that work for other companies. In either case
we find that we need to have or communicate some basic assumptions about any
given method.

This post will only cover how we communicate if a method will throw or not.

Will it throw exceptions?

Exceptions are, and should be exceptional. We believe methods should be written
and used with the expectation that they’ll succeed, as a matter of convention.
Which is not implying that you should not expect failure. It’s actually implying
that any normal method, should succeed at it’s intended operation or throw an
Exception if it can’t succeed for an exceptional reason that could be planned
for or controlled by the developer. Which communicates to the developer writing
the Caller method that the Callee may throw an exception and somewhere in the
call chain there should be an exception handler.

Then there are methods where failure is not exceptional, but part of the normal
and expected behavior. These methods are the exception to our convention of
“methods are expected to succeed or throw.”

This class of methods usually needs to test or attempt something that has a high
failure rate, is based on an input that hasn’t yet been sanitized, or requires
special handling of failures. An examples of such methods are the TryParse
methods found on many primitives, like int.TryParse. These are the methods of
Exceptional Behavior, in that failure is not exceptional, and exceptions should
not be thrown, because failure is an expected behavior.

Microsoft has published guidance as part of the .NET Framework guidelines
regarding two patterns they call the “Tester-Doer Pattern”, and the “Try-Parse
Pattern”, you can read more about these patterns here:
https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/exceptions-and-performance

The subject of exception handling and designing methods that communicate their
behavior when it comes to throwing exception is so near and dear to me, that I
have another blog entry similar to this one which can be found here:
https://blog.ramp51.com/2021/12/21/method-design-communicating-failures/ which
really digs in to the ideas around how you maintain consistent expectations for
the consumers of the methods you design when designing both methods of
conventional behavior and methods of exceptional behavior.

In a future blog posts we’ll get into another conventions and expectations
around methods as they pertain to blocking, reentrancy, idempotency, and purity.





--------------------------------------------------------------------------------

Categories
Self Improvement


BETTER TOMORROW BY PLAYING GAMES

 * Post author By Mark Squires
 * Post date January 25, 2022
 * No Comments on Better tomorrow by playing games



At Ramp51 we encourage everyone to do something today that makes them better
tomorrow. We look for inspiration in various places to help us remember to be
better tomorrow. Which brings us to the question:


CAN VIDEO GAMES MAKE YOU BETTER OR HELP SOMEONE YOU KNOW?

Jane McGonigal is the creator of a game called SuperBetter, which has helped
individuals cope and recover with issues like depression, anxiety, chronic pain,
and traumatic brain injury. Not to mention her best-selling books, research, and
PhD in game design. Check out this interview she gave with Shane Parrish at The
Knowledge Project

I often want to exercise my brain. I’ll do this occasionally by competing in
TopCoder, practicing some math on Kahn Academy I haven’t used in a while, or
through various other online activities . I hadn’t thought about the skills,
growth, self confidence that can be acquired when playing games. When I do, I
wonder; Why do kids believe they can conquer a boss in a video game? What makes
them ideate, practice and believe in their ability to do so? While the same kid
might give up on trying to to Factor in Algebra, or lack the confidence they
with some practice they could win the spelling bee. Is it a lack of inner drive?
satisfaction? interest? curiosity? fulfillment? support? encouragement? desire?
hope? It’s certainly not for a lack of ability.


WHAT ABOUT KIDS? IS IT GOOD, BAD, OR IT DEPENDS?

Jane says, there are three important questions, and you should ask your kids
about the games they are playing.

 1. What does it take to be good at this game? Skills? Personality? Temperament?
 2. What have you gotten better at by playing this game?
 3. What is the hardest thing you have accomplished in this game? How did you do
    it?

The ability to talk about what you have gotten better at helps you to bring
those skills to school, work, and your relationships.

Although Jane does think that you should limit your game time to 21 hours a
week. When should we use those 21 hours?

Are there better times of day for kids to play? If you want kids to retain what
they study better, you should have them play games first and then study before
they go to sleep. Which is related to an interesting ability for your brain to
focus on the most important problem while you are sleeping. However, another
caveat is that people who have been recently traumatized should find some relief
by playing a game before bed.

How often do you reflect on the previous day, and ask how the things you did
have made you better, and what you learned? It’s a fair question, and a lot of
us probably would admit we spend more time than we’d like on entertainment. If
you like playing games, maybe you can put it in the “self improvement” category
now.

Related Articles not linked above:

https://www.health.harvard.edu/blog/sleep-to-solve-a-problem-202105242463



--------------------------------------------------------------------------------

Categories
Software Development


INTEGER, LONG OR STRING: 10488084?

 * Post author By Mark Squires
 * Post date January 18, 2022
 * No Comments on Integer, Long or String: 10488084?



Today most enterprise software development requires integrating with systems
built by other teams and other companies. Often times those integrations need to
coordinate data and processes which means there is a set of shared identifiers
used by those systems to facilitate the integration.

When you are building an integration with another system, that returns and
identifier like 10488084, do you store it as an integer, long, or a string?

With a few exceptions that most of us developers don’t really need to deal with,
I would universally say it should be a string. Why should it be a string when
it’s clearly a number?

 * We aren’t performing any mathematical operations on it.
 * We don’t have any control of the identifier, or the range of values.
 * We likely don’t need to sort by ID, so whether the sort is numeric or
   alphabetic isn’t a concern.
 * Storage space is cheap. We don’t need to worry about the efficiency of
   storing the value as string vs a numeric type.
 * Performance on ID comparison is easily solved with data structures / indexes.
   Your database system is likely very capable at matching these strings
   quickly, even if it’s slightly slower then using numeric types.

Based on those reasons, any ID that is retrieved from a third party system
should be stored as a string. Which protects your system from changes in the
third party system. For example, if you store 10488084 as an integer in .NET,
and then the third party decides all new id’s will start at 3000000000, you have
a problem. The new ID’s will overflow and throw exceptions, unless you convert
them to longs or strings throughout your application. So you might as well start
with strings.

What are your thoughts? Any other reasons why we shouldn’t universally store
third party ID’s as strings?



--------------------------------------------------------------------------------

Categories
C# Style Best Practice Software Development


TO HELPER OR NOT TO HELPER

 * Post author By Mark Squires
 * Post date December 30, 2021
 * No Comments on To Helper or not to Helper



This is another RAMP51 best practices document.

In programming we use class names for expressing a purpose or a role that the
class plays in the system. When the purpose of our code is clear the name also
tends to be clear.

It’s common to hear advice that you should never name classes Helper or Utility.
I think most of us agree.

In the .NET Framework Reference source for .NET 4.7.2 there are 20,176 files,
among those files I found roughly 340 files named *Helper.cs

Microsoft is definitely a leader among leaders in terms of experience developing
frameworks and SDKs for others to use and consume. So the collective
intelligence of their developers and those that worked on the .NET Framework
would seem to indicate that there were times where they wanted something named
Helper.

I personally try to shy away from anything Helper because it’s easiest for its
creator to understand what belongs in the Helper and what doesn’t, but less
intuitive for your teammates.

Some times it’s definitely hard to find a name for one off utility methods. I
guess we could glean from the .NET framework code base a ratio of Helper files
to Non-Helper files, which would come out to roughly 1 helper file to 58 files
that aren’t named helper. This obviously assumes code files are spread evenly
across all assemblies and namespaces, which we know is not the case.

How many “Helper” or “Utility” files do you expect to see in your solutions? In
the classic ASP days I remember having one “junk drawer” include that just was a
grab bag of utility functions, and it worked ok. Often code would be duplicated
though. With today’s SAST tools we’d find these duplications fairly quickly.
Does it make sense to have junk drawer now? Or is nuget simply the junk drawer?
I’m still trying to name everything with a specific purpose in it’s context to
inform future developers as to the intent of how functionality should be
maintained and enhanced. So for now, I’m still keeping the junk drawer at home.



--------------------------------------------------------------------------------

Categories
C# Style Best Practice Software Development


METHOD DESIGN – COMMUNICATING FAILURES

 * Post author By Mark Squires
 * Post date December 21, 2021
 * No Comments on Method Design – Communicating Failures



How does a method name communicate failure expectations? When you call a method
what do you expect to happen if the method can’t accomplish what it’s meant to?

Will it throw an exception? Will it return some data that allows you (the
caller) to be aware of a problem?

It’s a tough situation as a developer, your boss, your teammates, the internet
all have their opinions and best practices to bestow upon you, like the
following:

 * Exceptions are heavy don’t overuse them
 * Handle exceptions gracefully
 * Expect failures and handle them

None of this advice is wrong. It will however lead you down a frustrating path
if they are not followed when and where appropriate. Above and beyond all of
that; the most important thing you can do to prevent failures is:

 * Effectively communicate expectations to the caller of the method you design
 * Effectively communicate expectations of the method to the future developers
   that need to maintain, use, or extend the functionality of this method

Without effective communication about the expectations of a method, code quickly
turns into spaghetti code trying to handle a bunch of oddball scenarios that
cause failures and bugs. Which in turn will complicate the ability of the GUI to
articulate these exceptions and errors to its end users. The problems surfaced
to the end users may have easy work arounds, or problems that are just total
failures, and the user should go away and come back later. Effectively
communicating failure, possible remediation, and total failure to your end user
can have a huge impact on how positive or negative the user experience is. Which
is the ONLY REASON we write code to begin with: to positively impact an end user
or stakeholder.

In C# when we call a method we usually want to understand the input and outputs
as quickly as possible. This way we understand what we need to pass in and what
we can expect to happen from calling a method with a given set of parameters.

When I’m choosing the name of my methods I usually name them in two ways:

 1. A name that communicates the expectation that the method will succeed when
    called, or an exception will be thrown.
 2. A name that communicates the expectation that the method will attempt an
    operation and the caller will need to perform some evaluation to determine
    if the call was a success. These methods will not throw exceptions, and
    usually would have a very tight focus on a single operation. An example
    would be int.TryParse the goal is to parse a string to an int, if it fails
    to do so it returns a false value indicating the string was not successfully
    parsed, and you now have to evaluate that boolean value of false to
    determine what you want to do next.

int.TryParse is an example of a method in .NET that communicates to the caller
that it will try an operation and return with a result that indicates if it was
successful. When you call methods in the .NET framework you expect them to
either throw an exception or complete successfully, such as int.Parse. These two
methods illustrate both categories above.

When a developer needs to maintain these functions it’s clear that one throws
exceptions, and one returns an indicator of failure (the returned boolean). So
the developer should know that he needs to maintain those expectations.

Where we get into trouble is when we do something like this:

Person p = datalayer.AddPerson(firstName, lastName);

Do you expect that line of code to throw an exception if it fails to add the
person to the database?

Do you expect p == null if that fails?

Do you expect p != null && p.Id == 0 ?

This is the type of ambiguity we find ourselves in when we deviate from the
pattern of throwing or bubbling up exceptions to whatever frame of the call
stack has the best chance to remedy the error. In some cases you can’t remedy
the problem and you just have to tell the user to try again later.

However when the problem can be remedied, we need a way to know it failed.
Exceptions are a consistent contract for understanding WHAT failed. If we go
back to the TryParse example, we find that when try parse fails we know it fails
but we don’t know why. Which may be ok because parsing an integer is so trivial
that we don’t care why, we just know we need to ask the caller for a better
value to parse. In our business logic these scenarios are usually more complex
with more dependencies and distributed infrastructure involved.

If you call AddPerson and you get a Connection exception because you can’t
connect to the database, then that should not be caught in AddPerson but let it
bubble up to whatever layer should handle it. In the case of a Connection
exception, let’s assume the configuration file is just configured with the wrong
connection. If this is executing inside a rest API the expectation of that
caller would be a 500, and internally in our code the exception would bubble up
to the Action “essentially the application layer”, and in that layer it would be
caught, logged, and return the appropriate 500 with a generic error message
indicate the server has an issue and to try again later.

The consumer of this api then doesn’t have to make any guesses about the
failure, and whether or not there was a problem with their request. If AddPerson
returned a 200, with some sort of error message in the payload the user would
need to decipher the error message. Once they sort out system errors from errors
the user can affect they then need to present them back to the end user in a
meaningful way to keep the user experience pleasant.

Surely there are valid use cases for such a contract but it creates complexity
because there is more opportunity for you to create an inconsistent response and
failure result between different types of operations.

Across boundaries like a call from one system to another system’s REST API there
is always a little bit of a need to understand the various exceptions and
response codes and translate those back to your use case and UX. However inside
a system the various calling methods and called methods should rely on a much
simpler and consistent contact, which is what I’m communicating above. Try
methods, and methods that throw exceptions.

As usual I’m just trying to lay out some best practices. Everything is
situational and quite frankly I’m going to probably put you to sleep if I try
any harder to explain this.



--------------------------------------------------------------------------------

Categories
C# Style Best Practice Software Development


DESIGNING METHODS FOR HUMANS

 * Post author By Mark Squires
 * Post date December 15, 2021
 * No Comments on Designing Methods for Humans



This post series will be focused on C# and techniques we try to use to maintain
high quality code intended to be read by humans. It will be opinionated in favor
of readability and intuitive method design. It won’t touch on concerns of
extremely high memory or high performance application requirements. These best
practices are just practices in general, not hard and fast rules.

A Method can be a lot of things in a software application. What it can be and
what the developer writing the calling method expects can be very different. So
how do we communicate the behavior of our methods in just a method name?

It’s not easy. We have to rely on some conventions. There is much to consider
when calling a method:

 * Will it throw exceptions?
 * Will it block?
 * Will it cause side effects?
 * Will it retry?
 * Will it be idempotent?

Those five concerns don’t even touch on the reason WHY you want to call the
method to begin with. What do you hope to gain from calling this method?

 * What will it return to you?
 * What will it do for you?
 * What does it need from you?
 * Does the method require the caller to handle the returned values with special
   care?

When a developer begins work on the codebase in the future are the caller’s
expectations of the method clear and obvious? If they aren’t it is easy for the
developer to change the method in a way that defies an expectation of the
caller; potentially breaking production code. Some of which is solved by a
strong unit test suite.

In the next post, I’m going to talk about how I design C# methods, to
communicate how the call should deal with failures or exceptions.

Feel free to comment if you think I missed anything or there is anything in
particular you would like to discuss or review.



--------------------------------------------------------------------------------

Categories
Anti-Predatory-Lending Compliance Illinois


IL ANTI-PREDATORY COMPLIANCE

 * Post author By Mark Squires
 * Post date February 17, 2021
 * No Comments on IL Anti-Predatory Compliance



Do you originate loans in the state of Illinois? You are probably aware of the
four counties that require loans to be registered with the IL Anti-Predatory
Lending Database.

Have you run into any of these problems?

 * A loan officer didn’t register a loan properly
 * A loan could not be sold to an investor
 * A loan was never registered or was registered improperly
 * A borrower wasn’t informed about their required home ownership counseling?
 * A closing agent either pulled an exemption certificate or asked your team for
   a compliance certificate when it wasn’t required.

Relieve some of the head aches and ensure your loans are compliant with this
regulation. LoanSiren will help you manage your pipeline to comply with the IL
APLD regulations.

Please leave a comment or send an email to mark.squires@ramp51.com if you have
any questions or would be interested in seeing a demo.



--------------------------------------------------------------------------------

Categories
C# Style Best Practice Software Development


IF-ELSE STATEMENT

 * Post author By Mark Squires
 * Post date February 10, 2021
 * No Comments on if-else statement



Great developers seek out patterns that prevent errors, unintended behaviors,
and promote readability. This post will discuss one of these best practices.

In the Microsoft C# documentation the “if” keyword is documented as part of an
“if-else” statement (if-else reference). The else part is important enough to be
included in the name of the statement.

if (object.property == SomeEnum.AnEnumValue)
{
   // do something
}


When you write an if statement similar to the example above; one of two things
is happening:

 1. You didn’t think about or plan for what should happen if the condition is
    false
 2. You did think about it; and you understand the code base well enough to know
    it’s not an issue

The if SHOULD be followed by an else-statement

if (object.property == SomeEnum.AnEnumValue)
{
   // do something
}
else
{
  // handle negative logic branch
}

Adding the else-statement here can force you to deal with the fact that every if
statement has two outcomes despite whether or not you’ve coded the
else-statement. It can also help communicate to other developers on your team
that the else-statement side of the branch has no negative impact on the logic
or state of the application.

Some developers will argue the code is cleaner, more concise and more readable
otherwise, and in most cases I’d probably disagree, of course there are
exceptions. A best practice is a guideline not a rule.

If you don’t have anything to code in the else-statement just add a comment, of
// intentional empty branch

if (object.property == SomeEnum.AnEnumValue)
{
   // do something
}
else
{
  // intentional empty branch
}

The reason for this is that it is ALMOST UNIVERSALLY TRUE that if the
then-statement side has a DESIRED effect on the state of the application, the
else-statement side has an UNDESIRED effect on the state of the application.

if (object.property != SomeEnum.Unknown)
{
   // do something, because the property is not set to the Unknown State of the enum
}
else
{
  // can't write code for a unidentified use case
  // must throw an exception, because there isn't a definition of how to proceed
  throw new InvalidOperationException("Object.Property, was set to Unknown");
}

Which could also be written in reverse

if (object.property == SomeEnum.Unknown)
{
  // can't write code for a unidentified use case
  // must throw an exception, because there isn't a definition of how to proceed
  throw new InvalidOperationException("Object.Property, was set to Unknown");
}
else
{
   // do something, because the property is not set to the Unknown State of the enum
}

Or even better using a optimistically named and descriptive conditional variable

bool isPropertyValid = object.Property != SomeEnum.Unknown;

if (isPropertyValid)
{
   // do something, because the property is not set to the Unknown State of the enum
}
else
{
  // can't write code for a unidentified use case
  // must throw an exception, because there isn't a definition of how to proceed
  throw new InvalidOperationException("Object.Property, was set to Unknown");
}

This practice is so essential because we tend to gravitate towards testing what
we expect to happen when writing if-else statements. To ensure that you don’t
make costly assumptions, it’s crucial to define what might happen if the
condition isn’t true.


Search for:


RECENT POSTS

 * The hovering laptop
 * Is IIF part of the VB.NET language?
 * Method Design – Exceptional Behaviors
 * Better tomorrow by playing games
 * Integer, Long or String: 10488084?


RECENT COMMENTS




ARCHIVES

 * August 2022
 * April 2022
 * March 2022
 * January 2022
 * December 2021
 * February 2021


CATEGORIES

 * Anti-Predatory-Lending
 * C# Style Best Practice
 * Compliance
 * Illinois
 * Self Improvement
 * Software Development
 * Visual Basic.NET

© 2023 Ramp51 Technology Blog

Powered by WordPress

To the top ↑ Up ↑